Skip to main content
This page covers the most common issues you may encounter when running AI-Implement and how to resolve them. If your issue is not listed here, check the dispatch log in the admin UI at /api/log and the GitHub Actions run logs in the target repo for additional detail.
The orchestrator polls for eligible issues every 60 seconds (configurable via POLL_INTERVAL_MS). If a triggered issue does not produce a PR after a few minutes, check the following in order:
  1. The issue is blocked. An issue is skipped while any issue linked as blocking it is still open. Resolve the blockers and the orchestrator will pick it up on the next poll. On Jira this check can miss silently — see A Jira issue ran despite an open blocker.
  2. No team/repo mapping exists. Open the admin UI at /admin and confirm that a mapping exists for the team that owns the issue. If not, add one.
  3. The concurrency cap is reached. Each project mapping has a maxInProgressAiIssues limit (default 3). If the project already has that many issues in progress (AI-Working on Linear, or AI-Implement Status set to Implementing on Jira), new issues are held until a slot opens. You can raise the cap from the admin UI or via PATCH /api/mappings/:teamKey.
  4. The orchestrator is not running or not polling. Health-check the orchestrator with curl https://your-orchestrator/. If it does not respond, check the Fly logs with fly logs --app your-app.
  5. The orchestrator has stopped picking it up. After repeated failed dispatches or runs it holds an issue back until someone intervenes, and the fix depends on which mechanism did it — see An eligible issue stopped being dispatched.
  6. Check the dispatch log. The log at /api/log shows whether the orchestrator attempted to dispatch the issue and what the outcome was.
An issue that was being picked up normally — correctly triggered, not blocked, with a project mapping and a free concurrency slot — quietly stops producing runs.Two mechanisms announce themselves on the ticket, and their fixes are not interchangeable. The comment tells you which one you have.⛔ AI-Implement parked this issue — the dispatch breaker. After enough consecutive failed dispatches for the same issue and phase, the orchestrator parks the issue and skips it from then on. The comment names the phase, the failure count, the last conclusion, and links to the failed runs. Nothing marks it in the Blockers panel, because parking is not one of the reasons that panel reports. Parked issues covers how parking is counted and what unparking changes.To release it, open Platform → Runners, find the issue in the Parked issues section, and click Unpark. Clearing the issue’s dedup entry does nothing here, because parking is tracked apart from the dedup ledger, and re-applying the trigger does not help either, since the orchestrator re-checks the park on every poll.AI Implementation Stuck — Needs Human — the retry budget. Once four runs for the same issue have failed or gone overdue, the orchestrator stops retrying and leaves the issue’s dedup entry in place so no poll picks it up. This one does reach the Blockers panel, under dedup — reported as waiting for an in-flight job, though the run it refers to has already ended. Overdue run recovery covers how that budget is counted.To release it, remove the issue’s entry from the Audit log. Unparking does nothing here — the issue was never parked.
Neither fix addresses what was failing. With the underlying cause still in place, the issue is dispatched, fails, and returns to the same state.
The orchestrator’s poll skips an issue while any issue that blocks it is still open, so an issue it dispatched anyway was never seen as blocked.Nothing marks the miss. There is no error and no log line, so the run itself is the only signal you get.On Jira the check recognizes only the default Blocks link type, matched by that name — unlike Linear, whose blocking relation is structural and cannot be renamed away. A Jira instance that renamed the link type gets no blocker check at all.To restore the check, have a Jira administrator rename the link type back to Blocks. To stop depending on it instead, leave the issue in any status other than the two the poll picks up, Ready and Plan Approved.Your mapping’s JQL cannot stand in for the check. It can exclude an issue from the query, but Jira’s query language cannot test whether the issue on the other end of a link is still open — that needs a marketplace app.
AI-Implement reports a failed run when the runner exits non-zero, or when an implementation run finishes without opening a pull request. The notification names the phase — planning or implementation — which tells you how far it got.
When a run fails, the orchestrator posts a run autopsy comment to the ticket, summarizing what happened and where it stopped. Check the ticket first — the post-mortem is often enough to point you at the cause before you dig into the logs.
Start with the run logs in the target repo’s Actions tab. The failure is almost always visible there, and the exit code in the notification points at which step ended the run.Common causes:
  • A setup: script declared in WORKFLOW.md exited non-zero, which aborts the run before Claude starts.
  • The push was blocked because the diff touched sensitive files. See sensitive file patterns for what the guard covers and how to tune it per project.
  • The run errored before pushing, leaving the branch incomplete.
When a run fails without producing a pull request, the orchestrator retries on its own rather than waiting for you: the failure clears the issue’s dedup entry, so the next poll dispatches a fresh job. An issue that keeps failing can spend several attempts this way before anyone looks at it.A run that fails but still pushes a draft pull request — Reached max turns, or a review that did not approve — is left alone deliberately, since the work is already on a branch waiting for a person.Once four runs for the same issue have failed or gone overdue, the budget is spent and the entry is kept instead — see An eligible issue stopped being dispatched for how to clear it.
This is a wall-clock limit, and it is not the same as Reached max turns — that one is a cap on how many steps Claude takes, not how long the run lasts. A run can hit either bound independently.Two wall-clock bounds exist:
  • The job timeout, which limits a GitHub Actions run. The default is 90 minutes. A run that passes it without finishing is detected as overdue and recovered, not left to hang.
  • The machine timeout, which ends a Fly Machine session 60 minutes after it is dispatched. This bound is fixed and cannot be configured.
Hitting either usually means the ticket was over-scoped for one run rather than that anything is broken. Splitting the ticket is the more reliable fix — a narrower issue finishes inside the budget and produces a reviewable diff.To raise the job timeout instead, open the project in the admin UI under Configure → Projects, choose Edit, and set Job Timeout (min). That covers /ai-implement comment-triggered runs as well.
Job Timeout (min) is only in the Edit dialog — the new-project stepper does not offer it. Create the project first, then reopen it to change the default.
The run finished and opened a pull request, but the post-push review used up its iteration budget without clearing every blocking issue. The pull request stays open and ordinary — the verdict is in its comments, not in its state.This is a working outcome, not an error — the review did its job. Read the review comments on the pull request: the last one ends with a merge-readiness line and lists what the review still considers unresolved against the original ticket.From there you can finish the work yourself, or comment /ai-implement with a specific instruction to send Claude back over the same branch.
The failure notice on the ticket may describe the work as “preserved in a draft PR” even when the pull request is not a draft. Trust the pull request over the notice.
The post-push review is skipped by design in three cases, so check these before treating it as a failure:
  • The run’s own review never approved the diff. The pull request still opens, but as a draft — or, on a repo whose plan does not allow drafts, as a normal pull request titled [NEEDS REVIEW — unapproved]. Either way no post-push review follows, because the review budget was already spent.
  • The run was a gap-fill. A /ai-implement pass updates a pull request that has already been through this, and never starts a second review cycle.
  • No pull request was opened. If Claude pushed commits without opening one, there is nothing for the review to run against.
If none of those apply, confirm the run actually reached the review step — check the GitHub Actions logs for the claude-implement.yml workflow, and fix any earlier failure first.
When provider is set to bedrock in a team mapping, the WORKFLOW.md (and PLANNING.md if planning is enabled) in the target repo must have a model: field in the front matter set to a valid Bedrock model ID or inference-profile ARN. There is no safe default for Bedrock.Open the target repo’s WORKFLOW.md and add or update the front matter:
Bedrock model IDs are specific to your account and region. Use the exact model ID or inference-profile ARN from your AWS Bedrock console.
Model IDs are passed through verbatim to the Claude CLI. A typo fails fast at invocation time with a clear error from Claude Code.
The claude-implement.yml workflow requires AWS_BEDROCK_ROLE_ARN to be set as a repository secret when provider=bedrock.Add the IAM role ARN in the target repo at Settings → Secrets and variables → Actions → New repository secret. The secret name must be exactly AWS_BEDROCK_ROLE_ARN. The role must trust the GitHub OIDC provider for the target repo and grant bedrock:InvokeModel on the inference profiles you need.See the AWS Bedrock setup instructions for the full IAM trust policy shape.
If a /ai-implement comment on a PR has no effect (no 👀 reaction, no new run), check the following:
  1. The GitHub App isn’t subscribed to PR comments. The App’s webhook settings must include the issue_comment event. Without this subscription, GitHub never delivers the comment to the orchestrator in the first place.
  2. GITHUB_WEBHOOK_SECRET isn’t set, or doesn’t match. The orchestrator verifies every delivery’s signature against this value; it must be set to the same secret on both the GitHub App’s webhook configuration and the orchestrator’s environment, or deliveries are rejected. See GITHUB_WEBHOOK_SECRET.
  3. The orchestrator isn’t publicly reachable. GitHub needs to reach the orchestrator’s webhook endpoint over HTTPS. For local development this needs a tunnel.
  4. The target repo hasn’t synced current workflow templates. Run Sync workflows on the project’s row in the admin UI and merge the pull request it opens — repos still on older templates aren’t recognized by the orchestrator’s webhook.
  5. The repo has no project mapping, or its project is paused. The comment is matched against the configured projects; one that matches nothing, or matches a paused project, is dropped without a reply.
  6. The PR wasn’t opened by AI-Implement. The trigger only works against PRs the orchestrator has a dispatch record for. PRs created by hand won’t match.
  7. Bedrock isn’t configured for the mapping. If the repo uses Bedrock, set Provider to bedrock and AWS Region on the project’s mapping in the admin UI — comment-triggered runs use the same mapping as orchestrator-initiated runs.
  8. The commenter does not have write access. The webhook checks that the commenter has write, maintain, or admin permission on the repo. Comments from users with lower permissions are silently ignored.
  9. The comment does not start with /ai-implement. The trigger matches comments that begin with /ai-implement. Anything you write after it is passed to the run as an operator instruction, so /ai-implement also update the tests works and is often more useful than the bare command. A comment that merely mentions /ai-implement mid-sentence does not trigger.
The admin API returns 401 Unauthorized when the bearer token is missing, invalid, or expired.
  • Confirm that ADMIN_ACCESS_CODE or a sign-in provider is configured on the orchestrator. With neither, the admin UI is disabled entirely.
  • Session tokens expire after 24 hours. Re-authenticate by POSTing to /api/auth with your access code to obtain a new token.
  • If you are accessing the UI through a browser, clearing your browser’s local storage for the admin origin and logging in again will resolve a stale token.
Notifications are silently skipped when NOTIFY_WEBHOOK_URL is not set. Check:
  • NOTIFY_WEBHOOK_URL is set as a secret or environment variable on the orchestrator.
  • NOTIFY_TYPE matches your provider (slack or teams). If unset, slack is the default.
  • The webhook URL is valid and the destination channel or Teams connector is still active.
You can verify the webhook manually by sending a test POST from your terminal.
A dedup entry is written when an issue is dispatched and stays until something clears it, so an entry can persist indefinitely. The admin UI’s Audit log section lists every event that clears one.If the same issue keeps being dispatched, check the dedup ledger:
  • Open the admin UI and go to the Audit log, or call GET /api/dedup.
  • If the issue has no entry, it was cleared and the orchestrator is treating the issue as new.
  • If the issue should not be redispatched, clear its trigger — remove the AI-Implement label on Linear, or move AI-Implement Status away from Ready on Jira. Adding an entry back by hand is not supported through the UI, so clearing the trigger is the simpler path.
If a Fly Machine session remains in the started state long after the implementation should have finished:
1

Open the sessions panel

Go to the admin UI at /admin and open the Active Sessions panel, or call GET /api/sessions.
2

Destroy the stuck session

Click the destroy button next to the session, or call DELETE /api/sessions/:machineId.Destroying the session also clears the in-progress marker on the associated issue (AI-Working on Linear, or AI-Implement Status set to Implementing on Jira) and clears its dedup entry.
3

Let it retry, or stop it

The orchestrator picks the issue up again on the next poll, because destroying the session cleared its dedup entry and left the issue marked for pickup. If you do not want it retried, remove the trigger before destroying the session.
A run ended with Reached max turns before finishing its work.
  • What a turn is. Each run gives Claude a fixed number of turns, where one turn is a single step in its work loop — it reads or edits something, runs a command, then decides what to do next. The run stops once it uses up the budget, even if the work is not done. The default budget is 50 turns.
  • Why it happened. The task needed more steps than the budget allowed — usually a large issue, or one that touches many files, though a run can also use up turns retrying the same thing.
  • How to fix it. Raise the budget with the Max Turns field: open the project under Configure → Projects, choose Edit, and set it there — the new-project stepper does not expose it. The setting covers /ai-implement comment-triggered runs as well. A higher budget lets one run do more work before it stops.
If runs keep hitting the cap after you raise it, the issue is likely too big for a single run — split it into smaller issues. A higher budget also means longer, costlier runs, so raise it deliberately rather than setting it very high by default.