// docs · v1.0

Troubleshooting

commitbrief doctor + recipes for common failures — wrong version, missing credentials, malformed JSON, guard aborts, OUTPUT.md template errors.

Symptoms and what they usually mean. For anything not on this page, commitbrief doctor is the first stop.

First-stop diagnostic — commitbrief doctor

commitbrief doctor

Runs eight checks against the resolved environment, then per-provider connection pings. Each row is prefixed with a status glyph ( green / yellow / red).

#CheckPass condition
1git binary on PATHexec.LookPath("git") succeeds
2config schema validMerged config non-nil and provider is set
3COMMITBRIEF.md sourceFile present, or falls through to embedded default
4OUTPUT.md template validTemplate parses and executes against empty + sample finding sets
5at least one provider configuredSome provider has an API key (or Ollama is active with base_url)
6active provider has credentialsconfig.provider itself has credentials
7cache directory writableCreate + delete a temp file under <repo>/.commitbrief/cache/
8.commitbrief/ in .gitignoreRepo .gitignore contains the entry

After the synchronous checks, doctor runs a per-provider connection ping for every provider that looks configured. Pings fan out concurrently with a 5-second timeout. A failing ping is a warning, not a fail — one broken provider out of three is recoverable.

Exit codes: 0 if zero StatusFail rows (warnings allowed), 1 otherwise. Safe to wire into CI as a config-validity gate.

commitbrief doctor --quiet

Suppresses OK rows and the heading — only warnings and failures plus the summary line. Useful in CI logs.

Common issues

git not found on PATH

Doctor reports ✗ git binary on PATH. CommitBrief shells out to git for several diff paths and cannot run without it.

Fix: install git via your platform’s package manager (brew install git / apt install git / winget install Git.Git).

active provider 'X' has no credentials

Doctor flags the active provider check. config.provider points at a provider whose api_key is empty (or base_url for Ollama).

Fix: either run commitbrief setup again to fill in the missing credential, or commitbrief providers use <name> to switch to a provider that already has credentials.

commitbrief --version shows the wrong version

You probably have two binaries on different points of $PATH. Typically: the Homebrew install at /opt/homebrew/bin/commitbrief and a go install build at ~/go/bin/commitbrief. The shell finds whichever is earlier in $PATH.

Diagnose: which -a commitbrief lists every match.

Fix: run the intended binary with an explicit path, reorder $PATH, or uninstall the one you do not want.

Splash logo shows raw ANSI escapes

Output is being captured / piped through a tool that does not interpret ANSI. The logo prints to stderr and is suppressed when stderr is not a TTY — if you are seeing raw escapes, your stderr is a TTY but the surrounding tooling is rendering it wrong.

Workaround: the logo never goes to stdout, so commitbrief --json | jq and commitbrief > out stay clean. To suppress the logo entirely, set NO_COLOR=1.

LLM produced malformed JSON; falling back to plain-text view

The provider returned a response that did not parse as the v1 findings schema. CommitBrief retries once with a stricter nudge; a second failure degrades to markdown rendering and emits this warning.

The plain-text body is still useful as a manual review, but --fail-on skips the threshold check (no structured findings to evaluate) and surfaces:

ℹ --fail-on skipped: LLM produced unparseable output, no findings to evaluate.

Probable causes: model running too cold (rare for current API providers), prompt size near the context limit, Ollama with a small model that does not honor JSON mode well. Switch to a larger model or check whether the diff is near the context window (commitbrief dry-run --verbose reports estimated tokens).

Aborted by pre-send guard

Your diff touches files under .commitbrief/ and either you are in a non-TTY context without --yes, or you answered no to the guard prompt.

Why the guard fires: .commitbrief/ files are usually user-specific (per-repo config, OUTPUT.md template) and committing them may break other developers’ configurations or leak API keys.

Fix: if the change is legitimate, run with --yes (or accept the prompt in TTY). If accidental, unstage the .commitbrief/ files: git restore --staged .commitbrief/.

Possible secrets detected in diff

The pre-send secret scanner found one or more credential-shaped strings on added lines. The scanner names the patterns but never prints the matched substring.

Fix: the most common cause is leaving a real key in source. Rotate the key, remove it from the diff (use environment variables, secret managers, etc.), and re-run.

If the match is a false positive (e.g. a test fixture), pass --allow-secrets to bypass for this invocation, or set guard.secret_scan: false if you have an external secret scanner doing the job. See Safety and cost.

Estimated cost: $X (threshold: $Y)

Cost preflight fired. Default threshold is $0.50.

Fix options:

  • Raise the threshold: commitbrief config set cost.warn_threshold_usd 5.0.
  • Skip the prompt: --no-cost-check.
  • Trim the scope (e.g. --file path/to/specific.go instead of --staged over a huge diff).

See Safety and cost.

argument list too long from a CLI-tool-backed provider

Rare — affects gemini-cli for very large diffs (the combined prompt exceeds the platform’s ARG_MAX, typically ~128 KB). claude-cli is not affected — it uses stdin transport.

Fix: for huge diffs, prefer claude-cli or one of the API providers. The diff size limit is a host-CLI constraint, not a CommitBrief limit.

OUTPUT.md template is invalid at …

Your repo-local or user-level OUTPUT.md does not parse or fails to execute against an empty / sample finding set. The pre-send validation catches this before any provider call so a bad template does not burn tokens.

Fix: the error message includes the parse error from text/template. Fix the syntax, or run commitbrief init --force to overwrite with the embedded default.

When in doubt

commitbrief doctor                       # health-check everything
commitbrief dry-run --staged --verbose   # inspect resolution + cost
commitbrief --version                    # confirm what you are running
commitbrief list                         # full reference + current config
commitbrief config show                  # resolved YAML, keys masked

See also