Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Troubleshooting

Each section starts from what you see, explains the cause, and gives the fix. Two commands answer most questions:

vibe task show <ref>     # status, last run, QA verdict, workspace
vibe doctor              # environment, configuration, keys, plugins

Where to look

SourceWhat it tells you
.vibe/tasks/NNN-slug/progress.mda timestamped note for every step: assessment, spec, plan, each subtask attempt with its failure reason, each QA round, merge result, pause reasons
.vibe/tasks/NNN-slug/run.jsonthe last run: status, current_phase, completed_phases, qa_round, last_error
.vibe/tasks/NNN-slug/events.jsonlevery event of every run: tool calls with their input, tool results, retries, agent stops
.vibe/tasks/NNN-slug/plan.mdeach subtask’s status, attempts and notes
.vibe/tasks/NNN-slug/qa_report_<n>.mdthe issues of each QA round
vibe history <ref>what each run did: phases, commits, changed files, validations, QA verdict, errors (History)
vibe trace <ref> [--full]every tool call of a run with its arguments, exit code and complete output (Tool call trace)
vibe events --since 1hthe recent activity of every task, in time order
standard error with -v, -vv, -vvvlogs at info, debug, trace level; RUST_LOG overrides
vibe trace 3 --tool bash --full      # every shell command of the last run, with its output
jq -r 'select(.event.type == "tool_returned" and .event.is_error) | "\(.event.tool): \(.event.preview)"' \
  .vibe/tasks/003-*/events.jsonl
RUST_LOG=vibe_agents=debug,vibe_plugins=debug vibe run 3 --resume 2> run.log

The file layout is described in Persistence layout.

The first model call fails with AuthFailed

AuthFailed: no API key configured for provider `anthropic` (set `api_key` or `api_key_env`)
AuthFailed: HTTP 401: invalid x-api-key sk-***

Cause. The provider’s key is missing, empty or wrong. Providers load without a key and only fail on their first call, so this appears at the start of assess or spec.

Fix. Export the variable named by api_key_env in the shell that runs vibe (ANTHROPIC_API_KEY or OPENAI_API_KEY for the built-ins), or switch to a provider you have (vibe run 3 --provider ollama). vibe doctor lists every declared provider, whether the configuration uses it, and whether their keys are set. Then resume: vibe run 3 --resume.

InvalidRequest: HTTP 429: You exceeded your current quota is a billing problem, not a rate limit: it is not retried. Check your account.

Retrying lines and rate limits

  ↻ retrying model call (claude-sonnet-5): HTTP 429: rate limit reached for requests (attempt 2, in 30.0 s)

Cause. A transient failure: rate limit (429), overloaded or server error (5xx), network error or timeout. Providers first retry silently, four attempts with exponential backoff (1 s doubling up to 60 s, honouring Retry-After); if the call still fails, the agent runtime retries it twice more, and those retries are the lines you see. Nothing to do unless it keeps happening.

Fix, if it persists. Lower pipeline.max_parallel_subtasks (each parallel subtask is a concurrent session), use a smaller model for high-volume phases ([phases.build]), or run fewer tasks at once. If all retries fail, the phase fails; resume the run later.

Retrying also appears for pipeline-level retries: plan: <validation error> when the planner produced an invalid plan, and subtask `…` before another attempt of a subtask.

ContextTooLong and continuation

Cause. A session grew past the model’s context window (many large files read, long command outputs). The provider reports it as ContextTooLong and the session stops with context_window.

What happens. Coder sessions (build) continue automatically: the transcript is summarised into handover notes and a fresh session resumes from them, up to five times. Other agents do not continue; their session ends with whatever they produced, which usually leads to the JSON problem below.

Fix. Use a model with a larger context for the phase, split the task, or make subtasks smaller by asking for it in the description. Large tool outputs are already truncated and saved under .vibe/tool-output/.

A model returns invalid JSON

agent `planner` did not produce valid structured output after a retry: no JSON object or array found in the output
agent `qa_reviewer` did not produce valid structured output after a retry: JSON does not match the expected shape: invalid type: string "none", expected a sequence

Cause. Structured agents must end with a JSON document. When extraction fails, the runtime makes one repair call, then resumes the agent once asking for valid JSON. A second failure is an error. What follows depends on the role:

RoleEffect of the error
complexity_assessorthe task falls back to standard
spec_gathererthe spec phase fails; the run is failed
spec_writer, spec_criticignored; the spec keeps the gatherer’s requirements (or the writer’s, for the critic)
plannercounts as a failed attempt; retried with the error as feedback, up to max_phase_retries more times
coder, coder_recoverya failed attempt of the subtask
qa_reviewerthe round is inconclusive: the run pauses with the task in review

Fix. Small local models are the usual cause: use a stronger model for the phase ([phases.plan], [phases.qa]), raise max_tokens of the agent if answers are cut, and see Writing prompts that return valid JSON if you replaced a prompt. Then vibe run <ref> --resume.

A subtask fails three times

  [2/4] Wire the export route                              failed
✓ build  3 done, 1 failed, 0 skipped

Cause. Each attempt ended without a coder report saying done. The third attempt (max_subtask_attempts) used the recovery agent. The reasons are in plan.md (the subtask’s notes) and progress.md; memory/gotchas.md records the failure for later runs. Subtasks that depend on it are skipped.

What happens next. If at least one subtask is done and none is pending, the run goes on to QA, which will likely request changes for the missing part. If nothing is done, the run fails with build failed: ….

Fix. Read why it failed. Often a verification command cannot pass in the worktree (missing service, missing tool, command denied). Fix the cause, then:

vibe run 3 --resume     # a failed build retries failed and skipped subtasks with a fresh budget

To finish the subtask yourself, do it in the worktree, commit, set its status to "done" in plan.json, and run vibe run 3 --from qa.

QA never approves

⏸ paused: QA did not approve after 3 round(s); human review needed
⏸ paused: issue `export ignores --limit with --json` was reported in 3 consecutive QA rounds; escalating to a human
⏸ paused: QA round 2 was inconclusive; human review needed

Cause. The run pauses with the task in review (exit code 2) when QA still requests changes after max_qa_rounds reviews in this invocation, when the same issue title appears in three consecutive reports, when a review is inconclusive, or when a trivial task, which has no fix phase, gets changes requested.

Fix. Read the latest qa_report_<n>.md. Then either:

  • let the agents try again: vibe run 3 --resume resumes at QA with a fresh round budget. An escalated issue that is still reported three rounds in a row pauses again, so change something first (a hint in progress.md, a stronger model for fix);
  • fix it by hand: edit and commit in the worktree (.vibe/worktrees/<slug>-<id>/), then vibe run 3 --from qa for a new review;
  • accept it as is: merge the branch yourself (see Workspaces).

If QA is wrong about a requirement, correct the requirement in spec.json before re-running QA; the reviewer checks acceptance criteria literally.

Merge conflicts

✓ merge  merge conflicts in 2 file(s)
Task 3 is ready · branch vibe/add-oauth-login-github-6f1c3e0a

Cause. With auto-merge, the base branch moved and the task branch conflicts with it. The workspace provider returned NeedsHumanReview: the merge was aborted, your checkout was put back on its branch and left clean, and the task is ready with the conflicting files listed in progress.md. The worktree and branch are left in place.

Fix. Merge by hand and resolve as usual:

git switch main
git merge vibe/add-oauth-login-github-6f1c3e0a

The merge is refused because the project is dirty

Automatic merge failed: cannot merge vibe/… : the project at /repo has uncommitted changes; commit or stash them first

Cause. Auto-merge works in your project checkout, and tracked files there have uncommitted modifications. Untracked files do not block it. The task ends ready.

Fix. Commit or stash your changes, then merge the branch by hand, or run vibe run 3 --from merge --auto-merge.

The worktree already exists

Cause. A task keeps its worktree between runs; running it again reuses it. A worktree directory that git does not know about (for example restored from a backup) is removed and recreated; a branch whose worktree was deleted gets a new worktree with its commits.

Fix. Usually nothing. If git itself complains that the branch is checked out elsewhere or the worktree is locked, clean up and retry:

git worktree prune
git worktree list
git worktree remove --force .vibe/worktrees/<slug>-<id>   # only if you want to start over

A project that is not a git repository fails before the run starts with /path is not a git repository: run `git init`, or use `--workspace in_place` .

A plugin fails to start

skipping plugin `jira`: Plugin: cannot start plugin `jira` (`jira-vibe-plugin` in `/repo`): No such file or directory
required plugin `policy` failed to start: …

Cause. The program is not on PATH, not executable, or crashes during the handshake. An optional plugin is skipped with a warning and the run continues without its tools; a plugin with required = true stops the run. The handshake times out after 60 seconds, a tool call after 600.

Fix. Run vibe plugins check: it starts each plugin, prints what it offers or the error, and stops it. Plugin standard error is logged at debug level, so add -vv. Details in Plugins.

A command is denied by the security policy

bash ⟵ error: Command denied by the security policy: `rm` may not target `/`

Cause. The shell policy blocked a segment of the command. The agent receives the reason and usually finds another way, so a single denial is not a problem. Repeated denials of a command the task really needs (a network client, docker, a database client) will make subtasks or QA fail.

Fix. Allow what is needed in [security]: allow_network = true for curl and friends, remove the program from blocked_commands, or add it to allowed_commands if you use an allowlist. System administration programs (sudo, mount, …) are always blocked. The rules are listed in Tools and security.

vibe says your home directory is not a git repository

error: /Users/me is not a git repository: run `git init`, or use `--workspace in_place`

Cause. Before 0.4.0, vibe looked for the nearest parent holding a .vibe directory without limit, and a ~/.vibe left by another tool made it take your home directory for the project. Since 0.4.0 the search stops at the git repository and never climbs up to the home directory; running vibe from the home directory itself still uses it, like any other directory.

Fix. Check which binary runs (vibe --version, which -a vibe) and reinstall if it is older than 0.4.0. With a current version, the project is the directory you are in (or the nearest parent with .vibe inside the same repository): run vibe from inside the repository, or name it with -C <dir>. The other tool’s ~/.vibe does not need to be removed.

.vibe/tool-output/ keeps growing

Cause. The trace store keeps the complete output of every tool call of every run, up to pipeline.trace_max_chars characters per call (100 000 by default), and nothing removes it automatically. Long test suites and verbose builds fill it fastest.

Fix.

du -sh .vibe/tool-output/*/                  # which tasks use the space
vibe task discard 3 --yes                   # a task you no longer need, with its outputs
rm -rf .vibe/tool-output/003-*/<run>        # the outputs of one old run only

To keep less, lower pipeline.trace_max_chars; to keep nothing but the previews in the log, set pipeline.trace_outputs = false. Removed outputs only make vibe trace --full fall back to the preview. The directory is ignored by git. Details in Tool call trace.

A vibe serve started by an application is still running

error: cannot listen on 127.0.0.1:7777
  caused by: Address already in use (os error 48)

Cause. An application (an editor, the macOS app, a script) started vibe serve as a child process and died without stopping it, for example after a crash or a kill -9. The orphan server keeps its port, its token file .vibe/server.token, and possibly runs.

Fix. Find it and stop it with SIGINT, which cancels its runs cleanly (they stay resumable) and removes the token file:

pgrep -fl "vibe.*serve"
kill -INT <pid>

An application that starts vibe serve should pass --exit-on-stdin-eof and keep a pipe on the child’s standard input: when the application ends, however it ends, the pipe closes and the server stops as on Ctrl-C. The macOS app does this. For a server you start by hand, --port 0 picks a free port.

vibe history shows ~, + or -

#  title          status  runs  commits  files  tokens  active      cost  finished
4  Add a cache    done    2     3        5~     84.1k+  3 min 10 s+ -     2 d ago

These marks are not errors:

  • ~ on files: the list of changed files is approximate. The task branch is gone and no merge was recorded, so the list comes from the commit events or from the files the agents wrote. vibe history <ref> names the source.
  • + on tokens or active time: a lower bound. A run was logged before 0.5 (its totals are unknown) or has not finished; vibe history <ref> shows which run.
  • + on the cost: some tokens were used outside a finished agent session (a session cut by a crash, or the repair of an invalid structured answer) and are not priced.
  • - as the cost: there is no [pricing] table, or a model the task used has no price in it (a local model needs a price of zero), or the task ran before 0.5 and its models are not recorded.

The detail also lists problems met while reading, such as a merge commit that git no longer has (after a rebase or a garbage collection): the history then falls back to the next source. See History.

Windows specifics

  • Shell commands run through cmd /C but are validated with POSIX shell rules, so cmd syntax such as %VAR% or ^ escapes may be denied as unparseable. Ask for plain commands in the task description, or pin the project’s commands in .vibe/agents/coder.toml.
  • Deep worktree paths can exceed 260 characters: git config --global core.longpaths true and enable long paths in Windows.
  • Antivirus scanners can lock files in target/ and make renames fail; exclude the project’s .vibe/worktrees/ directory.

The run was interrupted

A crash or a killed terminal leaves run.json with "status": "running". Ctrl-C leaves it cancelled. Both are resumable:

vibe run 3 --resume

Subtasks that were in progress go back to pending; completed ones are kept.

Resetting a task

GoalDo
re-run QA after manual changesvibe run 3 --from qa
re-plan from the same specvibe run 3 --from plan
redo the spec after editing the descriptionedit description in task.json, then vibe run 3 --from spec
re-assess the complexityset "complexity": null in task.json, or pass --complexity, then vibe run 3
forget the last rundelete run.json; artefacts stay
start completely overvibe task discard 3 --yes, then vibe task add again

A task keeps its complexity once assessed, so a plain vibe run 3 never calls the assessor again. --from starts a new run that reuses the files already on disk; delete spec.json or plan.json if you want them regenerated rather than reused by later phases.