Skip to main content
Experimental version.This is the latest in-development version of AI-Implement. Features may change without notice and behavior is not guaranteed. Switch to the latest stable version here.
Comprehensive reference for the error codes, statuses, and failure messages AI-Implement surfaces. For step-by-step fixes to the most common problems, see Troubleshooting.

HTTP API error codes

Error responses from the orchestrator’s HTTP endpoints.

Ticket comments

Status and progress comments AI-Implement posts on your issue.

Blocker reasons

Why an eligible issue was not dispatched.

Job status values

The states a dispatch moves through, end to end.

Run failure messages

Common planning and implementation failures, and how to fix them.

Issue lifecycle

The state diagram of triggers and transitions.

HTTP API error codes

The orchestrator’s HTTP endpoints return an error field on any failed request. The tables below list the errors each endpoint can return, grouped by who calls it: integration and callback endpoints used by runners and automation, and the admin API behind the admin UI.

Response body shapes

A failed request returns a JSON body with a single error field:
error
string
The error identifier that varies by endpoint.
  • For /runner/* and /trigger/gap-fill, a stable slug code (for example, missing_bearer).
  • For /api/* and the webhook, a human-readable message (for example, Invalid JSON body).
Some responses add fields alongside error, noted per endpoint below.

Integration and callback API

These endpoints are called by runners (GitHub Actions jobs, Fly Machine sessions, or local Docker containers) and by external automation, not from the admin UI. They do not use the admin session — each authenticates with a token or nonce tied to the run or trigger.

POST /runner/result

A runner reports the final outcome of a dispatch: success with a PR, or failure with error context.
HTTPerrorCondition
400invalid_bodyBody is missing or not a JSON object
400invalid_comment_shapeA comment entry is not an object with a string body
400invalid_commentscomments is missing or not an array
400invalid_outcomeoutcome is not success or failure
400invalid_phasephase is not planning, implementation, or gap-analysis
400missing_prUrlA successful implementation result did not include a PR URL
400phase_mismatchThe token’s phase does not match the body
401bad_signature, expired, malformed, wrong_audienceThe run token has a bad signature, is expired, is malformed, or is for the wrong endpoint
401missing_bearerMissing or malformed Authorization: Bearer header
409already_consumedThe single-use token was already consumed

POST /runner/progress

A runner streams step-by-step progress during a run.
HTTPerrorCondition
400invalid_bodyBody is missing or not a JSON object
400invalid_step_idstep.id is missing or not a string
400invalid_step_started_atstep.started_at is missing or not a string
400invalid_step_statusstep.status is missing or not a string
400invalid_step_typestep.type is missing or not a string
400step_requiredstep is missing or not an object
401bad_signature, expired, malformed, wrong_audienceThe progress token has a bad signature, is expired, is malformed, or is for the wrong endpoint
401missing_bearerMissing or malformed Authorization: Bearer header
404job_not_foundNo run matches the token

GET /runner/planning-context

A runner fetches the planning context for its run.
HTTPerrorCondition
401bad_signature, expired, malformed, wrong_audienceThe progress token has a bad signature, is expired, is malformed, or is for the wrong endpoint
401missing_bearerMissing or malformed Authorization: Bearer header

POST /trigger/gap-fill

External automation triggers a gap-fill run on an existing pull request.
HTTPerrorCondition
400issueKey and positive integer prNumber requiredissueKey is missing, or prNumber is not a positive integer
401unauthorizedMissing bearer token, or it does not match the trigger secret
404mapping_not_foundNo configured mapping owns an issue with this key
423project_pausedThe owning mapping is paused (response also includes teamKey)
501Gap fill trigger not configuredThe gap-fill trigger is not configured on this orchestrator
502dispatch_failedThe workflow dispatch to GitHub failed (response also includes detail and dispatchStatus)

POST /api/token

A session requests a short-lived GitHub token, issued against a one-time nonce.
HTTPerrorCondition
400nonce and owner are requirednonce or owner is missing
403Invalid or expired nonceNo active job matches the nonce
403Owner mismatchThe owner does not match the job’s repository owner
500Failed to generate tokenThe body was not valid JSON, or token generation failed

POST /api/status

A session posts a lifecycle status event, which becomes a comment on the issue.
HTTPerrorCondition
400event is requiredevent is missing or not a string
400Invalid JSON bodyBody could not be parsed as JSON
400nonce is requirednonce is missing or not a string
400Unknown event type: {type}event is not an allowed remote event type
403Invalid or expired nonceNo active job matches the nonce
500Internal server errorAn unexpected error occurred (for example, posting the status comment failed)

POST /api/step-report

A runner reports the status of a single pipeline step.
HTTPerrorCondition
400nonce is requirednonce is missing or not a string
400Invalid JSON bodyBody could not be parsed as JSON
400step is requiredstep is missing or not an object
400step.id is required and must be a stringA required step field (id, type, status, started_at) is missing or not a string
403Invalid or expired nonceNo active job matches the nonce
500Internal server errorAn unexpected error occurred while persisting the step

POST /api/github/webhook

GitHub notifies the orchestrator of pull-request events.
Events that don’t match a merged pull request return 200 and are ignored.
HTTPerrorCondition
400Invalid JSON payloadBody could not be parsed as JSON
400Missing required PR fieldsThe merged-PR payload is missing a required field (number, URL, branch, merge-commit SHA, or repository)
401Invalid signatureThe X-Hub-Signature-256 did not verify against the webhook secret

Admin API

These endpoints support the admin UI. See Admin UI for what each panel does.
Some sections below cover several related endpoints that return the same errors.
Every admin endpoint below requires a valid admin session except POST /api/auth.Requests without one return 401 with Unauthorized.

POST /api/auth

Exchange the admin access code for a session token.
HTTPerrorCondition
400Invalid request bodyBody could not be parsed as JSON
403Invalid access codeThe access code does not match

Job steps and issue lists

  • GET /api/jobs/{jobId}/steps returns a job’s step history
  • GET /api/issues lists tracked issues
  • GET /api/blockers lists issues currently blocked from dispatch
HTTPerrorCondition
404job not foundNo job with that ID
502(underlying error message)Fetching issues from the ticketing provider failed
Responses shown as (underlying error message) return the raw error text with a 500 or 502 status, not a stable code. Treat them as diagnostic detail — the wording can change between releases.

POST /api/mappings

Create or update a project mapping.
Every field validation returns 400 with a message naming the problem.
Required fields
HTTPerrorCondition
400defaultBranch is requiredNo default branch was given, and the mapping has none set
400Invalid request bodyBody could not be parsed as JSON
400teamKey, owner, and repo are requiredOne of these required fields is missing
Claude provider
HTTPerrorCondition
400awsRegion is required when provider is 'bedrock'provider is bedrock but no AWS region was given
400provider 'bedrock' is not supported with executionMode 'fly-machines'bedrock was combined with fly-machines
400provider must be 'anthropic' or 'bedrock'provider is some other value
Execution and resources
HTTPerrorCondition
400executionMode must be 'github-actions' or 'fly-machines'executionMode is some other value
400machineCpus must be a positive integermachineCpus is below 1 or not an integer
400machineMemoryMb must be an integer >= 256machineMemoryMb is below 256 or not an integer
400sessionMode must be 'autonomous', 'interactive', or 'hybrid'sessionMode is some other value
Other settings
HTTPerrorCondition
400branchPrefix invalid: {detail}The branch prefix is invalid
400extraEnv must be a plain objectextraEnv is set but is not an object
400extraEnv values must all be stringsAn extraEnv value is not a string
400maxInProgressAiIssues must be a positive integermaxInProgressAiIssues is below 1 or not an integer
400planningWorkflowFile is required when planningEnabled is truePlanning is enabled but no planning workflow file was given
400(ticketing validation message)The ticketing provider configuration is invalid

Mapping changes

  • PATCH /api/mappings/{teamKey} updates a mapping’s concurrency cap or paused state
  • DELETE /api/mappings/{teamKey} removes a mapping
HTTPerrorCondition
400Invalid request bodyBody could not be parsed as JSON
400maxInProgressAiIssues must be a positive integerThe new cap is below 1 or not an integer
400Specify either paused or maxInProgressAiIssues, not bothThe request set both fields at once
404Team not foundNo mapping with that team key
DELETE returns 404 with { "deleted": false } (no error field) when the mapping does not exist.

POST /api/mappings/{teamKey}/sync-workflows

Re-sync workflow templates into the mapping’s repository.
HTTPerrorCondition
404Team not foundNo mapping with that team key
500(underlying error message)The sync to GitHub failed

Jira configuration

  • POST /api/jira/validate-jql validates a JQL clause
  • GET /api/jira/fields lists Jira fields
  • GET /api/jira/field-options lists the options for a Jira field
HTTPerrorCondition
400Invalid JSON bodyThe validate-jql body could not be parsed
400fieldId query param required/api/jira/field-options was called without fieldId
400jql field requiredThe validate-jql body omitted jql
400(validation message)The JQL clause is invalid
500(underlying error message)The Jira request failed
501Jira not configuredNo Jira connection is configured on this orchestrator
/api/jira/field-options returns an empty list, not an error, when the field has no selectable options.

POST /api/runner-mode

Override the global runner execution mode.
HTTPerrorCondition
400Invalid request bodyBody could not be parsed as JSON
400mode must be one of: default, gha, fly, local, shadowmode is not a recognized value
409RUNNER_MODE env var is set; persisted to DB but has no effect at runtime until the env var is unsetThe value was saved, but a RUNNER_MODE environment variable overrides it at runtime

Sessions

  • GET /api/sessions lists active sessions
  • DELETE /api/sessions/{machineId} destroys a session
HTTPerrorCondition
500(underlying error message)Listing or destroying the session failed
503Fly sessions config not setDestroying a session while Fly sessions are not configured
GET /api/sessions returns an empty list, not an error, when Fly sessions are not configured.

Secrets

  • /api/mappings/{teamKey}/secrets lists, sets, and deletes per-team secrets
  • /api/global-secrets lists, sets, and deletes global secrets
HTTPerrorCondition
400Invalid request bodyBody could not be parsed as JSON
400name and value are requiredThe secret name is missing, or the value is missing or empty
400name must contain only letters, digits, and underscoresThe secret name contains other characters
400Secret name must not start with a team key prefix (...)A global secret name collides with a team prefix
404Secret not foundThe named secret does not exist (on delete)
404Team not foundNo mapping with that team key (per-team secrets)
500(underlying error message)The secret operation failed
503Fly sessions config not setSecrets require Fly sessions to be configured

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. There are two kinds: progress comments posted at each stage of a session run, and outcome comments posted when a run opens a PR or fails.

Progress comments

When a run executes in a session (Fly Machines or local Docker), AI-Implement posts a comment at each stage:
CommentWhen
🚀 Session machine created. Cloning repo and running setup…A session machine is provisioned
✅ Environment ready. Claude is implementing…The repository is cloned and dependencies are installed
📝 Claude finished. PR # opened: Claude finishes and opens a pull request
🧪 Running verification script…The verification script starts
✅ Verification passedThe verification script passes
❌ Verification failed: The verification script fails
🧹 Session machine cleaned up. Duration: The session machine is torn down
⚠️ Session failed: . Machine will be cleaned up.The run errors out
⚠️ Session timed out: . Machine will be cleaned up.The run exceeds its time budget
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.
{reason} is the underlying failure message from the run.See Run failure messages for what these messages contain and how to resolve them.
Log labelMeaning
container_failedThe local Docker container exited with an error
container_timeoutThe local Docker session exceeded its lifetime
machine_timeoutThe session machine exceeded its lifetime
post_push_review_not_approvedA PR was opened, but the post-push review flagged blockers
pr_not_foundThe run finished but did not open a PR
session_failedThe session run failed

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 dedup window passes — but no-mapping needs you to add a project mapping.
ReasonMessage shownWhen
concurrency at concurrency cap (/). Waiting for a slot.The team is at its maximum number of in-progress issues
dedupAlready dispatched recently. Waiting for the in-flight job.The issue was dispatched within the last 24 hours
no-mappingNo mapping for team . Add one in Projects.The issue’s team has no 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 dispatch 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.
StatusTerminalMeaning
unknownNoInitial state, before a run is linked
dispatchedNoThe workflow was dispatched; awaiting a run
runningNoThe run is in progress
completedYesThe run succeeded and a PR was opened
review_failedYesA PR was opened, but the post-push review flagged blockers
failedYesThe run errored, or finished without opening a PR
timed_outYesThe run exceeded its time budget
A timed_out status carries one of these reasons:
ReasonMeaning
container_timeoutThe local Docker session exceeded its lifetime
machine_timeoutThe session machine exceeded its lifetime (around 60 minutes)
run_not_foundA run was never linked within the time limit (around 10 minutes)
timed_outThe GitHub Actions run reported a timeout
For how completion statuses appear in Slack or Teams, see Notifications.

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.
Example: Implementation failed: LLM invocation failed with exit code 1 … Reached max turns (50)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.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.

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:
StageLinear labelJira status
TriggeredAI-Implement (you add)Ready
PlanningAI-PlanningPlanning
Plan completePlan-CompletePlan Approved
ImplementingAI-WorkingImplementing
PR openedReady for ReviewPR Ready
Planning failedAI labels removed, plus a commentPlanning Failed
Implementation failedAI labels removed, plus a commentImplementation Failed