Troubleshooting and FAQ
Why did my item stop?
A work item that needs you shows needs human on the board. Find out why before you retry: a retry without the cause reruns the same failure.
kraft view show ID # the node it stopped on, and the reason
kraft view events ID --type work_item_needs_human # the stop, with every field
kraft view logs ID # the last agent session's log
In Claude Code, /kraft:triage reads all three and suggests the next step.
Find the reason in the first column. Where a fix says retry, run
kraft item retry ID, and add --steer "..." to tell the agent what to do
differently. A retry you run resets the node's attempt counters.
| The reason says | What happened | Fix |
|---|---|---|
needs_context: <question> | The agent asked a question it could not answer from the repo. | Answer it: kraft item resume ID --steer "<answer>". |
task failed in node <node>: ... | An agent task or command failed. | Read kraft view logs ID, then retry with a steer that names the fix. |
task failed in node <node>: ..., and kraft view logs ID shows an authentication or login error | The agent CLI is installed but not logged in. kraft admin doctor checks only that it is on PATH. | Run the agent once in a terminal and log in (claude for the shipped chains), then kraft item retry ID. |
could not start <task> in node <node>: ... | Kraft refused the launch. The rest of the reason says why. | Fix the named cause, often with kraft admin doctor, then retry. |
... nothing registers it for Claude Code: ... | No kraft MCP server is registered, so Kraft refused a Claude worker. | Install the Kraft plugin and run /kraft:onboard, or run kraft admin init. Then retry. See the tutorial. |
<loop> exhausted after N fix cycle(s) | A fix loop spent its attempts without passing. | Read the findings (kraft view events ID --type findings_measured), then retry with a steer. |
<gate> exhausted after N rejection(s) | A gate was rejected as many times as its chain allows. | Retry with a steer, or rework the spec or plan yourself. |
stuck: ... | A fix loop made no progress across cycles. | Kraft starts an escalation turn on its own, up to three times. If it still stops, send a message with kraft item escalate ID --message "...", or retry with a steer. |
a repair in node <node> finished with concerns ... | A repair ran, but its agent doubted the result. | Read the concerns in the reason, then retry with a steer, or kraft item skip ID. |
<scope> is read_only, but it changed the worktree: ... | A read-only step edited files. | Look at the named files, then retry. |
the conflict in node <node> cannot be resolved ... | Rebasing onto the base branch hit a conflict nobody resolved. | Resolve it in the worktree (cd "$(kraft repo path ID)"), commit, then retry. |
<worktree> has a <name> in progress: inspect it, then delete ... | The worktree holds a rebase, merge, cherry-pick, revert, bisect or autostash Kraft did not start, so Kraft would not rebase or commit over it. A sandboxed worker can plant this to move one of your branches. | Look at the named file first. If you did not leave it there yourself, delete it as the reason says, then retry. Never run git rebase --abort, git merge --abort or --continue on it: that is what moves the branch. |
<worktree> is not on <branch>; check it out by hand, then retry | The worktree's HEAD names another branch, so Kraft would not commit, rebase or push from it. | cd "$(kraft repo path ID)", check that nothing of yours is on the named branch, git checkout <branch>, then retry. |
origin/<branch> is at <sha>, which Kraft did not push and this worktree does not have ... | Someone pushed commits to the item's merge request branch, and Kraft's push would have overwritten them. | cd "$(kraft repo path ID)", git pull --rebase origin <branch> to bring them in, then retry. |
origin no longer has <branch>, which Kraft pushed ... | The item's branch was deleted from origin, usually with its merge request merged or closed. Kraft won't recreate it. | If the work should still be published, run the two git update-ref -d commands the reason names in the item's worktree, then retry. Otherwise abandon the item. |
work item <id> runs sandboxed, and its workspace members <paths> are not the checkouts Kraft made ... | A member of the item's worktree is not the checkout Kraft made from its connected repository. A sandboxed worker may have swapped it, or the item started before Kraft checked members out this way. Host git there would read config the worker can write. | Abandon the item and file it again, which checks each member out afresh. |
workspace member <path> of <worktree> has no checkout Kraft made ..., this sandboxed launch was not given the checkout of workspace members ..., setup command for <id> cannot run: its sandbox was not given the checkout ..., <path> is not a directory; the member under it is not mounted, or ... cannot be made in the sandbox's ref store ... | A sandboxed launch would have mounted a member Kraft could not check against its connected repository, or reach without a symlink, so it did not start. | Retry. If the member's checkout changed, the check before the next task names it. If it recurs, report it as a bug. |
<id> runs sandboxed, and no connected repository is known for <paths> ... | A member's repository is not connected, so Kraft has nowhere safe to check it out from. | Connect it with kraft repo connect PATH, then retry. |
member <path> of <id>: the connected repository <path> for <path> is missing ... | The member's repository is no longer at the path repos.yaml gives. | Reconnect it (kraft repo connect PATH), or fix its path in repos.yaml, then retry. |
member <path> of <id>: the connected repository <path> for <path> is not the top of a git repository ... | The path repos.yaml gives for the member is a directory inside some other repository, so git there would act on that one. | Fix the member's path in repos.yaml to the repository's own top directory, then retry. |
member <path> of <id>: <repo> already has a branch <branch> at <sha>, not at <sha> ... | The member's repository already has a branch with the item's name, somewhere other than the commit the root points at. Kraft won't check it out and replace what the root records. | Look at that branch in the member repository. Move it to the named commit or delete it, then retry. |
budget cap reached: ... on this work item | The item's own dollar cap refused the next launch. | Click Raise budget on the item, or run kraft item raise-budget ID --usd N: either raises that cap and retries. See Caps and budgets. |
budget_usd reached ..., token budget reached ... | 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 does not appear, and raise-budget is refused. | For the work item, raise it with kraft item set-policy ID --policy budget_usd=N (or token_budget=N), up to maxima.work_item, then retry. For a path, the item-wide value also lifts it, unless that node, step or task sets its own cap in the chain. That one only tightens under set-policy (PATH.budget_usd=N can lower it, not raise it), so this item cannot raise it: skip that node with kraft item skip, or raise the cap in the chain and file the item again. The item's policy was fixed when it was filed, so editing policy.yaml or the chain reaches only items filed afterwards. See Raising a cap. |
budget cap reached: ... today, across every work item | The daily cap refused the next launch. Raise budget does not appear, and raise-budget is refused. | Raise budget.daily_usd in policy.yaml, or wait for local midnight, then retry. |
budget_usd cannot be checked: N launch(es) in ... reported no cost, and unknown spend is never counted as free ... | A launch in that scope ran on a harness that reports tokens but no cost (Codex, Cursor, Amp), on a model prices.json cannot price, so Kraft cannot show the scope is under its budget_usd and will not count the launch as free. Raising budget_usd does not help: the stop stays while any budget_usd applies to the scope. | Clear the item-wide cap with kraft item set-policy ID --policy budget_usd=none (add --policy token_budget=N to keep a bound), then retry. That 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: 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. See Harnesses that report no cost. |
kraft: a process in the sandbox was killed by its memory limit (<size>), or ... under its <size> memory limit (the runtime did not confirm it was the limit) | The sandbox's memory limit killed the task. In the second form Docker never confirmed it, but the container exited 137 under the limit and Kraft did not stop it. | Raise resources.memory in the sandbox policy, or make the task need less, then retry. See sandboxed workers. |
the Kit <ref> cannot be used: ..., or the Kit <ref> has not been fetched here yet ... | The item's sandbox is a Kit Kraft could not fetch, or will not run. | See A Kit is refused. |
<scope> hit its time cap of N minutes | A time cap ran out. | Raise it for this item, then retry: kraft item set-policy ID --policy time_cap_minutes=240. See Raising a cap. |
gate <gate> waited past its timeout of N minutes | Nobody decided a gate in time. | Retry to reopen the gate, then decide it. |
<task> timed out waiting ... | An external wait (CI, a review) ran out. | See Waiting on CI or a review. Retry once the outside is fixed. |
rate_limit retries exhausted after N attempt(s) | The agent's provider kept refusing for a rate limit. | Wait for the limit to reset, then retry. |
| CI or automated-review failure, with a suggested retry | CI failed for its own reasons, or a cancelled run has no successor. | Retry once CI has recovered. |
... are executed by the running Kraft daemon ... | A task that runs inside Kraft itself failed. | Update and restart Kraft (kraft admin update --restart), or skip the node. |
executor crashed: ..., reattach ..., resume: ... | Kraft crashed or restarted while the item ran. | Retry. If it happens again, run kraft admin doctor and open an issue. |
A pending gate is not a stop. It waits for your decision:
kraft item approve ID or kraft item reject ID --note "...".
If the work is heading the wrong way rather than failing, pause it and resume
it with a steer: kraft item pause ID, then kraft item resume ID --steer "...".
To move past a node without running it, use kraft item skip ID.
The events catalogue lists every field of a stop.
A Kit is refused
An item whose sandbox is a Kit reads the Kit before its worktree is made. If that fails, the item stops needing you, and the reason names the Kit and why. The same check runs again before each task; there a failure ends that task's launch as a configuration error, and nothing runs outside the sandbox. The rest of the reason says which:
| The reason goes on | Fix |
|---|---|
`manifest inspect <ref>` failed: ..., or under Podman `pull -q <ref>` failed: ... or `image inspect <ref>` failed: ... | The CLI could not read the Kit: a wrong reference, a missing registry login, or a registry it does not trust. Check it with docker manifest inspect <ref> as the user Kraft runs as. |
<ref> is not a Kit: no vnd.docker.sandbox.kit.descriptor annotation | The image was not built with the Kit frontend (# syntax=docker/sandbox-kit:3). |
requires <type>; Kraft does not enforce it, is a kind: mixin ..., has a capability group ... | The Kit needs something Kraft does not run. Mark the capability optional: true, or remove it, and rebuild. Docker's published Kits are refused this way: build one for Kraft. |
credential service '<service>' has no binding ... | Add <service>: <DAEMON_ENV_NAME> under credentials in sandbox.yaml, and set that variable in the daemon's environment. |
A dotted path and a message, such as capabilities.1.config.apiKey: ... | The descriptor does not decode: fix the Kit at that path. |
has not been fetched here yet | A review, gate review, escalation turn, or a read through the artifacts or diff API ran before any task fetched the Kit. Retry the item. |
Fix the Kit or the policy, then kraft item retry ID. A changed Kit is a new
digest: put it in kit: in repos.yaml and file the item again, since its
sandbox is fixed when it is filed.
Waiting on CI or a review
merge_request_feedback waits on "no checks yet". The pull request has no
CI checks, so nothing will ever pass. Add CI that runs on pull requests, set
ci_checks: false on the repo's entry in
repos.yaml so both CI waits, before and
after the merge, pass at once, or
file the item on the quick-task chain. Otherwise Kraft keeps checking until
the wait's timeout, then stops the item.
external_approval keeps waiting. A branch rule on the forge requires an
approving review. Have someone else approve the pull request, or remove the
rule. Kraft checks again on its own.
Kraft won't start: port already in use
If something already answers on Kraft's port (8765 by default), kraft
refuses to start and says what it found:
kraft: refusing to start - something is already answering on 127.0.0.1:8765. curl http://127.0.0.1:8765/api/health to inspect it, or `kraft admin stop` if it's yours.
When it names a Kraft server, that is an instance you already started:
kraft admin stop stops it. Otherwise pick another port. kraft admin start --port 9000 moves only the server; to have the kraft command, the plugin and
the VS Code extension follow it, set port in
access.yaml instead.
Common kraft admin doctor failures
kraft admin doctor runs every check and exits 1 if any fails. kraft admin health checks only the server.
| Row | What it means | Fix |
|---|---|---|
home (a warning) | No server has ever run on this KRAFT_HOME. templates, harnesses.yaml and the tokens fail until one has. | Start kraft once, then run doctor again. |
server | Nothing answers on the configured address. | Start it: kraft, or kraft admin start --detach. |
health: invalid policy or invalid template | policy.yaml or a chain file does not load. Kraft refuses new work. | Fix the named file, then kraft admin reload. kraft admin templates lint checks every chain. |
health: orphaned agent sessions | After a restart, Kraft could not confirm some sessions. | Retry the affected items. |
mcp server | No kraft MCP server is registered, so Claude workers are refused. | Install the Kraft plugin, or run kraft admin init. |
mcp server (a warning) | A connected repo has no kraft MCP server registration of its own, often because its committed .claude/settings.json turns the plugin off. An unsandboxed task there on the harness the row names is refused; a repo whose items run sandboxed or on another harness is unaffected. | Register it for that repo (kraft admin init --repo), or ignore it if no unsandboxed Claude task runs there. |
agent: <profile> | The agent CLI is not on the server's PATH. | Install it. Under a service, the unit's PATH counts, not your shell's; run kraft admin uninstall-service, then kraft admin install-service from a shell where the CLI works. See Run Kraft as a service. |
cost: <harness> (a warning) | That harness reports no cost, and the chains launch it on a model prices.json cannot price, or on no model (the CLI's default). budget.work_item_usd, budget.daily_usd and --budget count its spend as $0; a budget_usd stops on it. | Give its tasks or profile a priced model, or bound them with token_budget. See Harnesses that report no cost. |
kraft on PATH | An older kraft comes first on PATH. The MCP server and hooks run it. | Uninstall the other one, or reorder PATH. |
sandbox <repo>: the Kit <ref> is refused: ... | The repository's Kit cannot be fetched or will not run, so each item there stops. | See A Kit is refused. |
kit hosts <repo> (a warning) | The Kit does not allow a host a harness requires, so that harness's sessions under it are refused the host. | Add the host to the Kit's runtime allow list and rebuild it, or run that harness elsewhere. |
kit credentials <repo> (a warning) | An optional Kit credential has no binding in sandbox.yaml, so it is skipped. | Add <service>: <DAEMON_ENV_NAME> under credentials in sandbox.yaml. |
forge <repo> | gh or glab is missing, or the repo has no forge recorded. | Install the forge CLI and log in, or set forge: on the repo. |
repo <repo> | A connected repo's path is gone or is not a git repo. | Reconnect it, or kraft repo disconnect PATH. |
duplicate <repo> (a warning) | A repo you connected and a submodule checkout Kraft detected are one repository: usually a member you connected on its own, and its root's submodule. A workspace member naming the second runs with none of the first's settings. | Point the workspace member at the entry you configured (workspaces: in repos.yaml), then kraft repo disconnect the other. |
mcp token, trigger token | The token file is missing, or other users can read it. | Start the server once to write it, or chmod 600 it. |
pidfile | The pidfile names a process that is gone. | Nothing. The next kraft admin start clears it. |
worktrees | A worktree has no work item. | Check it for work you want, then delete it. |
spa bundle | This install has no web UI. | Reinstall from a release. |
FAQ
Does Kraft work only with GitHub? No. Kraft opens and merges changes on
GitHub through gh and on GitLab through glab. A repo's forge is recorded
when you connect it, from its origin.
Can I use it without Claude Code? Partly. Kraft ships six
harnesses: Claude, Codex, Cursor, OpenCode, Gemini and
Amp. Every agent task in the shipped chains names Claude, so to run without it
you change each task's harness:. See
Switch a task to another harness. Any agent that speaks MCP can drive Kraft
with kraft admin mcp, and any shell can use the kraft command.
What does it cost? Kraft is free and Apache-2.0 licensed. Your agent
provider bills you for the sessions Kraft runs. The shipped policy.yaml caps
spend at $10 per work item and $50 per day. See
Caps and budgets.
Does it run on Windows? No. Kraft supports macOS and Linux. WSL is untested. See Supported platforms.
What makes a good spec? Start with a good description: it is the brief the
spec is written from, and the title is only a label. A good spec names the
problem in the repo's own terms, the approach and the options you rejected,
what is out of scope, and the tests that prove it. If you already have a spec
or plan, attach it (kraft item create --spec PATH --plan PATH), and Kraft
skips writing and approving it again.
Kraft or Kraft Lite? Use Kraft when work should run without you watching, in its own worktree, across sessions and restarts, with a board and caps. Use Kraft Lite when you want the same chain and gates inside one agent session, with no server to run.
Can I approve each tool call myself? No. A worker runs unattended, and
Kraft's permission gate answers each tool call from
the task's policy, never by asking a person. To control what a worker may do,
set allowed_tools, deny_tools and grants, run it in a
sandbox, and review its
work at the gates between nodes.