Skip to main content

API error codes

Error responses from the orchestrator’s HTTP endpoints.

Troubleshooting

Step-by-step fixes for the most common problems.

Issue, dispatch, job and run

This page uses four words for four different things:
  • Issue — the ticket in Linear or Jira that you flag.
  • Dispatch — the orchestrator starting a workflow for that issue.
  • Job — the orchestrator’s record of one dispatch, and what carries a status.
  • Run — the workflow execution itself, and what produces a failure message.
One issue can accumulate several jobs over time, and each job is matched to at most one run — a job whose run never appears is the run_not_found case below.

Issue lifecycle

AI-Implement moves each issue through a fixed set of stages. The diagram shows the stages and what moves an issue between them.
See Triggers and status indicators for how each stage maps to a Linear label or Jira status, and how to re-run after a failure.
Each stage shows up as a Linear label or a Jira status:

Ticket comments

AI-Implement comments on the issue it is working so you can follow a run from your issue tracker, without watching the admin UI or the GitHub Actions logs.
  • Progress comments — posted at each stage of a session run.
  • Outcome comments — posted when a run opens a pull request or fails.
  • Run stats — a per-pass breakdown, posted when the review approved the work.
  • Run autopsy — the same breakdown when it did not.

Progress comments

When a run executes in a session (Fly Machines or local Docker), AI-Implement posts a comment at each stage:
Each comment also includes a timestamp, and a link to the machine logs when one is available.

Outcome comments

These report how a run finished:
  • A pull-request link, posted when the run opens a PR.
  • A failure notice when a run errors out: ⚠️ Planning failed: {reason} or ⚠️ Implementation failed: {reason}.
  • A log excerpt, posted on a terminal failure or timeout and labeled with the context below.
  • An explanation of the outcome, posted whenever a run did not finish cleanly.
{reason} is the underlying failure message from the run.See Run failure messages for what these messages contain and how to resolve them.
What the explanation says depends on how the run ended: Each one also links to the troubleshooting guide. A run that finished cleanly gets no explanation, and neither does a sweep that tidied up an issue already marked done — there is nothing to account for.

Run stats and autopsy

An implementation run closes with a table of its passes, one row each:
  • The iteration number
  • What the implement pass did
  • How many turns it took
  • What it cost
  • Whether review approved it
Which comment carries that table depends on how the run ended:
  • Run stats, when review approved the work. Adds the total cost across passes, and compares the files the plan declared against the files the run actually changed.
  • Run autopsy, when it did not. Names the reason the run stopped, quotes the reviewer’s final feedback, and links the draft pull request holding the work — or says none could be opened, when the run produced no changes at all.

Blocker reasons

The orchestrator checks for eligible issues on a schedule. When it skips one, the Blockers view in the admin UI shows why. Most reasons clear on their own once the condition changes — a slot frees up, or the issue’s dedup entry is cleared — but no-mapping needs you to add a project mapping.
An issue is also skipped if it has open blocking issues linked to it. That is a separate eligibility check, not one of the reasons above.
For step-by-step help when an issue is not picked up, see Troubleshooting.

Job status values

Each job moves through these statuses, shown in the dispatch log and the issue list. Non-terminal statuses describe a run still in flight; terminal statuses are the final outcome and do not change afterward. A timed_out status carries one of these reasons: For how completion statuses appear in Slack or Teams, see Notifications.

Overdue run recovery

A run does not hang forever when it stops reporting back. The orchestrator checks every job on its poll cycle and recovers the ones that have gone quiet. A run is overdue once it has stayed non-terminal for its project’s configured Job Timeout (min) plus a short grace period, counted from the moment its job was dispatched. The run hit the time limit covers where that timeout is set and how to raise it. Recovering one, the orchestrator:
  • Cancels the workflow run, when one was ever linked to the job.
  • Clears the issue’s in-progress marker and its dedup entry, which together are what make it eligible again.
  • Leaves the next poll to dispatch a fresh job against the same issue.
A job whose run never appears at all reaches the same recovery after ten minutes, and reports run_not_found as its last run status.
The retry is bounded to three attempts, counted per issue and shared with ordinary run failures, so a mix of the two draws down one budget. On the fourth, recovery stops, and the orchestrator instead:
  • Posts an AI Implementation Stuck — Needs Human comment on the ticket, naming the attempt count and the last run.
  • Sends a notification, when a webhook is configured to receive one.
  • Leaves the dedup entry in place, so no poll picks the issue up again.
An eligible issue stopped being dispatched covers how to tell this apart from a parked issue, and how to clear it.

Run failure messages

When a planning or implementation run fails, AI-Implement posts the reason on the issue as ⚠️ Planning failed: {reason} or ⚠️ Implementation failed: {reason}. The {reason} pairs a short note about which step failed with the underlying error from the tool involved (Claude, git, or the package manager). The most common failures are listed below.
Claude stopped because it reached the maximum number of turns allowed for a single run — the work was too large to finish in the limit, or the run got stuck repeating steps.Unlike the other failures on this page, this isn’t a hard error: the run still pushes its work as a draft PR (carrying the reviewer’s final feedback and per-pass stats) and posts a run-autopsy comment on the ticket with a per-pass breakdown, rather than failing with a bare invocation error.See Troubleshooting for information on how to raise the limit.
Example: Implementation failed: LLM invocation failed with exit code 1: …Claude’s run ended with an error rather than completing — for example an API error or a loss of context. The exit code and the end of the message point to the underlying cause.
Example: Implementation failed: Nothing to commit: Claude left no file changes in the working treeClaude finished without changing any files, so there was nothing to open a pull request with. The issue may already be addressed, or may need more detail before a re-run.
Example: Implementation failed: PR creation failed with HTTP 422: …AI-Implement could not push the branch or open the pull request — commonly branch protection rules, missing repository permissions, or a pull request already open for the branch.
Example: Implementation failed: git clone failed (exit 128): …The runner could not clone or check out the target repository — commonly repository access or permissions, or a missing branch.
Before pushing, AI-Implement scans the staged files for anything that looks like a secret. If a staged file matches a sensitive pattern, it blocks the push and marks the implementation failed rather than risk committing a credential.On the issue you’ll see a comment that starts with 🔒 Blocked by security guardrail, followed by Push blocked: N sensitive file(s) would be committed: and then each offending file with the reason it was flagged.A file is flagged when it falls into one of these categories, with a few examples of each:
  • Environment and config files — .env, secrets.yml, or a credentials.yml.enc.
  • Private keys and certificates — .pem and .key files, or an SSH key like id_rsa.
  • Cloud credentials — an AWS credentials file, a GCP service-account JSON, or a .tfstate.
  • Database credentials — a .pgpass file or a database.yml.
  • Tokens and auth files — .npmrc, .netrc, or a kubeconfig.
To resolve it, remove the file from the change, or add it to .gitignore so it’s never staged, then re-run the issue.