v2.0.0next
Troubleshooting

Stop reasons in detail

The stop reasons that need more than one table row, each with what it means and the numbered fix.

These are the stop reasons that need more than one row to fix. The tables under Find your reason link here from each one.

Forge authentication fails

The stop's facts.cause is forge_auth, and the card reads Failed with the fix under it.

Kraft holds no forge token. It runs gh (GitHub) or glab (GitLab), and git, as the user the server runs as, and the forge refused what they sent. Nothing in Settings › Repos can supply a token.

  1. On the machine the server runs on, sign the forge CLI in: gh auth login, or glab auth login for GitLab.
  2. If git itself still cannot authenticate, check its credentials: gh auth setup-git, your SSH key or credential helper. gh auth status shows who the CLI is signed in as. kraft admin doctor checks only that the CLI is installed, not that it is signed in.
  3. Run kraft item retry ID.

no forge is recorded for this repo

The repo had no GitHub or GitLab origin when you connected it, so Kraft does not know which forge CLI to run.

  1. Set forge: github or forge: gitlab on the repo in Settings › Repos, then Review & publish (or set it in repos.yaml).
  2. Run kraft item retry ID.

declares neither test_scopes nor test_command

The item stops at its test node (verify on quick-task, verification on default) because Kraft will not guess a test command.

  1. Set test_command (or test_scopes) on the repo in Settings › Repos, then Review & publish, or set it in repos.yaml. For a repo with no tests, set "". kraft repo connect PATH again saves the command it now proposes.
  2. Run kraft item retry ID.

nothing registers it for Claude Code

No kraft MCP server is registered, so Kraft refused a Claude worker. The item stops at its first agent step with 0 tokens spent: spec on default, implementation on quick-task.

  1. Install the Kraft plugin and run /kraft:onboard, or run kraft admin init.
  2. Run kraft item retry ID.

kraft admin doctor's mcp server row checks the same thing: see The mcp server warning.

stored model override is not a model id

A model override on the item or a node holds text that is not a model id, such as sonnet 4. The reason ends with the stored text.

  1. Run the command the reason names, kraft item set-overrides ID --clear or kraft item set-node-override ID --node N --clear, or set a valid model.
  2. Run kraft item retry ID.

Before 2.0, an override could hold any text, so an old item can still carry one.

no user.name configured

The same stop names user.email when that is the missing one. git has no commit identity for the repo, so Kraft would not make the item's worktree: its commits would fail or carry an invented author.

  1. Set both for the user Kraft runs as, for every repo:
    git config --global user.name "Your Name"
    git config --global user.email you@example.com
    

    To set them for one repo, run the same commands without --global inside it.
  2. Run kraft item retry ID.

no setup_command declared

The repo has no setup_command, and Kraft will not guess what to run in a fresh worktree. This is the usual first stop on a repo with no lockfile Kraft knows (see How connect proposes commands). The item stops at its first node.

  1. Set setup command on the repo in Settings › Repos (or setup_command in repos.yaml). If the repo has nothing to install, tick No setup needed there instead ("" in repos.yaml).
  2. In Settings, click Review & publish: until you do, the change is a draft and the retry stops again.
  3. Run kraft item retry ID.

Git would not start the rebase

Nothing was rebased. Most often the base now tracks a file the worktree has untracked, such as a note or a script the agent never committed, and git will not overwrite it.

  1. cd "$(kraft repo path ID)".
  2. Look at the files git names, then move, delete or commit them.
  3. Run kraft item retry ID.

A uv.lock the setup command wrote and nobody changed is not one of these: Kraft sets it aside for the rebase. One that an older release recorded without a digest is kept in place, in case the agent edited it: see Upgrade from 1.4 or an older release.

A git operation is in progress

The worktree holds a rebase, merge, cherry-pick, revert, bisect or autostash. A sandboxed worker can plant one to move one of your branches. A rebase of Kraft's own that was cut short (a server killed mid-rebase, or an abort that could not run) leaves one too.

  1. Look at the named file first. If you did not leave it there yourself, delete it as the reason says.
  2. If deleting it leaves HEAD detached, check the item's branch out again with git checkout -f <branch>, as the reason names it. The branch still has the item's commits.
  3. Run kraft item retry ID.

Never run git rebase --abort, git merge --abort or --continue on it: that is what moves the branch.

A policy budget or token cap refused the launch

A policy budget_usd or token_budget refused the next launch. The message names the scope: the work item, or a node, step or task path in backticks.

raise-budget is refused for a token_budget or a path, and the item's page offers Retry with no raise. Raise a cap on a stopped item has the fix for each scope: Raise cap or kraft item raise-budget for the item-wide budget_usd, kraft item set-policy for a token_budget, and for a cap the chain sets on a path, kraft item skip or a change to the chain.

The item's policy was fixed when it was filed, so editing policy.yaml or the chain reaches only items filed afterwards.

A budget cap cannot be checked

A launch in that scope ran on a harness that reports tokens but no cost, on a model prices.json cannot price. Kraft cannot show the scope is under its budget_usd and will not count the launch as free. Which harnesses these are is on Harnesses that report no cost.

Raising budget_usd does not help: the stop stays while any budget_usd applies to the scope.

  1. Clear the item-wide cap with kraft item set-policy ID --policy budget_usd=none. Add --policy token_budget=N to keep a bound.
  2. Run kraft item retry ID.

The budget_usd=none fix clears a cap from the chain's own policy:, repos.yaml or a policy.yaml default too, but is refused under a maxima.work_item.budget_usd, and does not lift a cap the chain set on a node, step or task. For those, skip that node with kraft item skip, or bound that harness's scopes with token_budget in place of budget_usd and file the item again.

Copyright © 2026