Last updated: v2.10.0
Indexed by ERROR_CODES. When a validator fails, look up the .code value
from its ValidationError here.
Debug flag: set DOTBABEL_DEBUG=1 to route previously-silent git-probe
catches (resolveRepoRootFromGit, getChangedFiles) to stderr tagged
[harness:git:*].
SPEC_JSON_INVALIDdocs/specs/<id>/spec.json is missing or fails to parse.
Fix: node -e "JSON.parse(require('fs').readFileSync('docs/specs/<id>/spec.json','utf8'))" to locate the parse error, or create the file.
SPEC_STATUS_INVALIDstatus is not one of draft | approved | implementing | done.
Fix: pick a valid status. Only approved|implementing|done gate PR coverage.
SPEC_ID_MISMATCHspec.json.id does not equal the directory name.
Fix: rename the directory or update id — they must match.
SPEC_MISSING_REQUIRED_FIELDA required field (title, owners, depends_on_specs, active_prs, …) is missing or wrong type.
Fix: the pointer on the error tells you which field.
SPEC_LINKED_PATH_MISSINGlinked_paths is missing, empty, or contains a non-string entry.
Fix: every entry must be a non-empty string glob or path.
SPEC_ACCEPTANCE_EMPTYacceptance_commands is empty or contains a non-string entry.
Fix: at least one command that CI can run.
SPEC_DEPENDENCY_UNKNOWNdepends_on_specs references an id that does not exist under docs/specs/.
Fix: create the dependency spec or remove the reference.
MANIFEST_ENTRY_MISSINGA .claude/skills-manifest.json entry points at a path that does not exist on disk.
Fix: remove the entry, or restore the file.
MANIFEST_CHECKSUM_MISMATCHA file’s content drifted from the recorded sha256.
Fix: npx dotbabel-validate-skills --update to recompute and accept the new content, or restore the file to its original state.
MANIFEST_ORPHAN_FILEA file under .claude/commands/ or .claude/skills/<name>/SKILL.md is not indexed in the manifest.
Fix: npx dotbabel-validate-skills --update to pick it up (add a manifest entry), or delete the file.
MANIFEST_DEPENDENCY_CYCLEThe dependencies[] graph has a cycle.
Fix: break the cycle. The error .got field shows the path A -> B -> A.
COVERAGE_UNCOVEREDA protected path changed in the PR but no approved|implementing|done spec covers it, and the PR body has no ## No-spec rationale section.
Fix: draft a covering spec (status ≥ approved) or add a rationale to the PR body.
COVERAGE_NO_SPEC_RATIONALEThe PR body has neither a ## Spec ID nor a ## No-spec rationale section, but protected files changed.
Fix: add one of the two sections.
COVERAGE_UNKNOWN_SPEC_IDThe PR body references a Spec ID: that does not exist under docs/specs/.
Fix: check the spec directory, or create the spec first.
DRIFT_TEAM_COUNTAn instruction file (CLAUDE.md, README.md) mentions N team(s) with N ≠ docs/repo-facts.json team_count.
Fix: update either the file prose or repo-facts.json.team_count.
DRIFT_PROTECTED_PATHA docs/repo-facts.json protected_paths entry is either non-string or
absent from a file listed in rule_floor_files.
Fix: add the entry to CLAUDE.md §Protected paths, regenerate generated
instruction files with dotbabel-generate-instructions, or remove it from
the facts file.
DRIFT_INSTRUCTION_FILESinstruction_files is missing/non-array, or rule_floor_files is present but
invalid in docs/repo-facts.json.
Fix: add instruction_files as a non-empty array, e.g.
["CLAUDE.md", "README.md"]. If rule_floor_files is present, make it a
non-empty array of files that must mirror protected-path rules.
DRIFT_INSTRUCTION_FILE_MISSINGAn instruction_files entry points at a path that does not exist.
Fix: create the file or drop the entry.
DRIFT_GENERATED_STALEA generated rule-floor output differs from what
dotbabel-generate-instructions would write.
Fix: run npx dotbabel-generate-instructions and commit the generated
outputs.
SCAFFOLD_CONFLICTdotbabel-init refuses to overwrite an already-initialized repo.
Fix: pass --force to overwrite, or remove .claude/skills-manifest.json / docs/specs/ first.
SCAFFOLD_USAGEBad CLI invocation of dotbabel-init (e.g. flag without a value).
Fix: see --help.
validate-settings.sh)SETTINGS_SEC_1A *_KEY / *_TOKEN / *_SECRET field in ~/.claude/settings.json holds
a literal 20+ character value. Fix: replace with ${ENV_VAR} reference.
SETTINGS_SEC_2skipDangerousModePermissionPrompt is set. Fix: remove it.
SETTINGS_SEC_3An MCP server args include @latest. Fix: pin the version.
SETTINGS_SEC_4~/.claude/.credentials.json is not mode 600. Fix: chmod 600 ~/.claude/.credentials.json.
SETTINGS_OPS_1Settings JSON is malformed OR an MCP command / hook target / enabled plugin does not resolve. Fix: read the specific message — it names the unresolved target.
SETTINGS_OPS_2~/.claude/projects/ or ~/.claude/file-history/ exceeded its disk budget.
Fix: the warn message includes a find … -delete command to prune.
ENV_REPO_ROOT_UNKNOWNcreateHarnessContext() could not resolve a repo root.
Fix: pass --repo-root <path> or DOTBABEL_REPO_ROOT=<path>, or run inside a git worktree.
ENV_FACTS_MISSINGdocs/repo-facts.json is missing or unreadable.
Fix: scaffold with dotbabel-init or author the file (see plugins/dotbabel/templates/docs/repo-facts.json).
USAGE_UNKNOWN_FLAGAn unknown flag was passed. Exit 64. Fix: see --help.
USAGE_MISSING_POSITIONALA required positional argument is missing. Exit 64. Fix: see --help.
These issues apply when using the bootstrap path (./bootstrap.sh) rather than
the npm CLI. They are not ERROR_CODES — they are runtime observations.
Check the symlink exists:
ls -la ~/.claude/commands/pre-pr.md
ls -la ~/.claude/skills/aws-specialist/SKILL.md
If missing: re-run ./bootstrap.sh. If present: restart the Claude Code session
(/clear or quit and reopen) — the session may have cached the pre-bootstrap state.
Skills are fanned out to ~/.codex/skills/<id>/SKILL.md and ~/.gemini/skills/<id>/SKILL.md during dotbabel bootstrap. Two reasons a skill might be missing there:
$PATH. Bootstrap only fans out to a CLI it can find. Re-run with dotbabel bootstrap --all (or ./bootstrap.sh --all) to force fan-out even when the CLI isn’t installed yet.$CODEX_HOME and $GEMINI_HOME override the default ~/.codex and ~/.gemini parents. Check the active values:echo "$CODEX_HOME" "$GEMINI_HOME"
ls -la "${CODEX_HOME:-$HOME/.codex}/skills/<id>/SKILL.md"
ls -la "${GEMINI_HOME:-$HOME/.gemini}/skills/<id>/SKILL.md"
dotbabel doctor validates these symlinks resolve when the matching CLI is on $PATH.
The session cached an older version. Run ./sync.sh pull (or dotbabel sync pull)
to fetch the latest, then restart the session.
Specialist skills (e.g. aws-specialist) activate when their trigger phrases appear
in your message. Ensure the phrase matches — e.g. write “AWS Lambda” not just
“lambda”. If still not triggering, check that the skill’s SKILL.md is present:
ls ~/.claude/skills/aws-specialist/SKILL.md
bootstrap.sh backed up files I didn’t expectBootstrap backs up any real file (not a symlink) at a target path before replacing
it. Backups are named <name>.bak-<timestamp>. Review them before deleting. This
is intentional — bootstrap never silently overwrites your existing work.
sync push refuses with “secret scan failed”The push-side scan detected a likely secret (*_KEY/*_TOKEN/*_SECRET pattern
or AWS key format). Review the flagged file and remove the secret. To bypass for
a known-safe file (e.g. a test fixture with a fake key):
HARNESS_SYNC_SKIP_SECRET_SCAN=1 ./sync.sh push
search, list, show) return “index missing”Run dotbabel index first to build the artifact index. The index is generated
from agents/, skills/, commands/, etc. and must be rebuilt after adding or
renaming artifacts.
dotbabel index
dotbabel search kubernetes
These apply to any Claude Code skill (SKILL.md), independent of the dotbabel
bootstrap. They mirror the failure modes in Anthropic’s Agent Skills guidance.
Claude Code only discovers a skill when its file is named exactly SKILL.md
(uppercase SKILL, lowercase .md) and lives inside its own named
subdirectory — skills/<name>/SKILL.md, never a bare file at the skills root.
A mismatched filename or a SKILL.md sitting directly in the skills root is
silently skipped. Surface loader errors with:
claude --debug
That is Claude Code’s own loader debugging — distinct from dotbabel’s
DOTBABEL_DEBUG=1 (documented at the top of this page), which only traces the
CLI’s git probes, not skill loading.
Skill selection is semantic, matched against each skill’s description. When two
skills have overlapping descriptions, Claude may pick the wrong one. Make each
description distinct — narrow the scope and the trigger phrases so they don’t
collide. dotbabel-validate-skills warns when two artifacts claim the same
trigger phrase, which is an early signal of this.
A higher-priority skill with the same name shadows yours. Enterprise skills
(pushed through managed settings) carry the highest priority and override
personal, project, and plugin skills of the same name — and cannot be overridden
locally. Rename your skill, or ask your administrator which managed skill is
claiming the name.
Runtime failures during execution usually trace to one of:
description so it is visible before invocation.chmod +x on any script the skill executes./) in every path, even on
Windows; backslashes break cross-platform resolution.