fallow doctor
Find out if fallow can see your project correctly before you trust its results. Fallow doctor runs read-only checks on the project root, config, workspaces, plugins, the optional type-aware companion, dependencies, and caches.
A misconfigured project can give output that looks clean but is wrong. fallow doctor checks your setup without running an analysis, so you know if you can trust the results of other commands. It checks:
- that the project root is readable
- which config resolved
- that workspace discovery found the packages you expect
- that the external plugins load
- that the optional type-aware companion is present
- that the dependencies are installed
- that the persisted caches are compatible with the project
Each check is a local read. You can safely run doctor as the first command on a repository that you have never analyzed. It is also fast enough for a CI preflight step.
fallow doctor
fallow doctor --format json
doctor only tells you if fallow can see your project correctly. It does not analyze your code. When it reports ready, run fallow dead-code and fallow health to analyze the code.
Checks
| Check | Category | Required | What it answers |
|---|---|---|---|
root | project | Yes | Is the project root an accessible directory? |
config | configuration | Yes | Which config resolved, or did zero-config defaults apply? |
workspaces | workspace | No | Did workspace discovery complete, and how many packages did it find? |
plugins | plugin | Yes | Do the configured external plugins load? |
type-aware | companion | No | Is the optional type-aware companion enabled and available? |
dependencies | project | No | Is a node_modules directory present, or does the project run without one? |
cache | cache | No | Can the extraction cache be loaded with the current configuration? |
graph-cache | cache | No | Can the module-graph cache be loaded for this project root? |
When a check that is not required cannot run, it reports skipped. A skipped check never fails the command. The type-aware check is skipped when type-aware analysis is off, which is the default.
The last three checks can only warn. They cannot fail, so they never change the exit code.
dependencieswarns when the project has nonode_modulesdirectory and needs one. Until you install the dependencies, fallow gives less accurate results for packageexports, plugin activation, and dependency classification.cacheandgraph-cachewarn when a persisted blob exists but a run would discard it. The warning gives the reason and the size on disk. A project with no cache yet passes, because a first run has no cache.
A project with one of these warnings reports the aggregate warn and still exits 0.
There are two cache checks because a run reuses the two blobs independently. The extraction cache can be reusable while fallow rebuilds the module graph on every run. graph-cache checks that the blob loads and belongs to this project root. A pass does not prove that a run will reuse the blob. The reuse decision also compares resolver options, entry points, and per-file content hashes. To compute those, fallow must run discovery and extraction, and doctor does not do that.
When FALLOW_CACHE_DIR is nonempty, it sets the cache location and takes priority over the configured cache directory. Fallow resolves relative paths against the project root, the same as during analysis.
- An absent cache is normal on a first run.
- An unreadable cache gets a separate report with a hint about the path and permissions.
- A decoding failure can mean an older cache format or damaged data. It does not prove corruption. When you rebuild the cache, it uses the current format.
Options
| Flag | Default | Description |
|---|---|---|
--root <ROOT> | current directory | Project root directory. |
--config <CONFIG> | discovered | Path to the Fallow config file. |
--format <FORMAT> | human | Output format: human or json. Alias: --output. |
--pretty | off | Indent JSON output. |
--quiet | off | Suppress progress output. |
doctor reads and never writes, so it rejects --output-file. The report goes to stdout, and the files that doctor checks do not change. doctor runs no analysis, so it also rejects analysis and gate flags such as --production and --fail-on-issues. It does not ignore them silently.
Exit codes
| Code | Meaning |
|---|---|
0 | Every required check passed. Warnings still exit 0. |
2 | A required check failed, so the project is not ready to analyze. Also an invalid flag or format, such as --production, --output-file, or --format sarif. |
doctor never exits 1. That code means error-severity findings. doctor checks your setup and not your code, so it has no findings.
Human output
Fallow doctor (.)
[OK] root: Project root is an accessible directory.
[OK] config: Configuration resolved from .fallowrc.json.
[OK] workspaces: Workspace discovery completed (30 workspace packages).
[OK] plugins: No external plugins are configured; built-in detection remains available.
[-] type-aware: Type-aware analysis is not enabled.
[OK] dependencies: Dependencies are installed, or the project runs without a node_modules directory.
[W] cache: Extraction cache (0.9 MB) would not be reused: cache format version changed. The next run parses every file.
Action (from project root): fallow dead-code --quiet
[OK] graph-cache: Module-graph cache (0.5 MB) loads; a run reuses it when the analysed files and options are unchanged.
Status: ready with warnings
The last line gives the status: ready, ready with warnings, or not ready. When a check has a remediation, it prints the remediation on an indented Action line under the message.
JSON output
{
"kind": "doctor",
"schema_version": 2,
"version": "3.31.0",
"root": ".",
"status": "warn",
"summary": {
"pass": 6,
"warn": 1,
"fail": 0,
"skipped": 1
},
"checks": [
{
"id": "root",
"category": "project",
"status": "pass",
"required": true,
"message": "Project root is an accessible directory."
},
{
"id": "config",
"category": "configuration",
"status": "pass",
"required": true,
"message": "Configuration resolved from .fallowrc.json."
},
{
"id": "workspaces",
"category": "workspace",
"status": "pass",
"required": false,
"message": "Workspace discovery completed (30 workspace packages)."
},
{
"id": "plugins",
"category": "plugin",
"status": "pass",
"required": true,
"message": "No external plugins are configured; built-in detection remains available."
},
{
"id": "type-aware",
"category": "companion",
"status": "skipped",
"required": false,
"message": "Type-aware analysis is not enabled."
},
{
"id": "dependencies",
"category": "project",
"status": "pass",
"required": false,
"message": "Dependencies are installed, or the project runs without a node_modules directory."
},
{
"id": "cache",
"category": "cache",
"status": "warn",
"required": false,
"message": "Extraction cache (0.9 MB) would not be reused: cache format version changed. The next run parses every file.",
"remediation": {
"command": "fallow dead-code --quiet",
"cwd": ".",
"mutating": false
}
},
{
"id": "graph-cache",
"category": "cache",
"status": "pass",
"required": false,
"message": "Module-graph cache (0.5 MB) loads; a run reuses it when the analysed files and options are unchanged."
}
]
}
The top-level status is pass, warn, or fail. The status of a single check can also be skipped.
A check can have a remediation object with command, cwd, and mutating:
cwdis always the project root.mutatingtells you if the command writes anything. An agent can run the read-only commands without asking.
If you pass --config with a project-relative path that is safe to render, the remediation command repeats it. For an external config path, or a path that is not safe to render, fallow omits the command. The message then tells the caller to use the same --config value again.
For agents
Run fallow doctor --format json --quiet before the first analysis on an unfamiliar repository. A clean project and a misconfigured project can both give empty results, and doctor is the fastest way to tell them apart. Branch on the top-level status. Then read checks[].message to tell the user what to fix.