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.
  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. Check the dispatch log. The log at /api/log shows whether the orchestrator attempted to dispatch the issue and what the outcome was.
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.
Once you have fixed the cause, re-dispatch by removing and re-applying the trigger. The failure already cleared the issue from the deduplication window, so it is eligible again immediately.
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 ends a GitHub Actions run. The default is 90 minutes.
  • The maximum session age, which applies to Fly Machine runs. Sessions older than 4 hours are destroyed by the reconciliation sweep. 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) — this applies to both orchestrator-initiated and /ai-implement comment-triggered runs on a repo synced to the current workflow templates. AI_IMPLEMENT_MAX_JOB_MINUTES on the target repository only has effect on repos still running the older, pre-sync comment-trigger.yml workflow.
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 found blocking issues it could not resolve within its iteration budget. The pull request is left as a draft so it does not read as ready to merge.This is a working outcome, not an error — the review did its job. Read the review comment on the pull request: it lists what the review considered 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. Mark the pull request ready for review once you are satisfied.
The post-push review only runs when the implementation step succeeds and an open PR is found on the branch after implementation. If no review comment shows up:
  • Confirm that the Claude run succeeded and that a PR was actually opened. Check the GitHub Actions run logs for the claude-implement.yml workflow.
  • If Claude ran but did not open a PR (e.g. it pushed commits to an existing branch without creating a new PR), the review is skipped by design.
  • If the workflow run failed before reaching the review step, fix the underlying 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 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.
  6. 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.
  7. 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.
  8. 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 is set on the orchestrator. If the variable is unset, 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:
  • A failed or timed-out run clearing its own entry
  • A session being destroyed
  • An operator clearing it
Nothing ages out on a timer, so an entry can persist indefinitely. If the same issue keeps being dispatched, check the dedup entries:
  • Open the admin UI and go to the Deduplication panel, or call GET /api/dedup.
  • If the issue is not in the dedup window, it means the dedup entry was cleared (manually or by a session-destroy action) 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 issue back into the dedup window 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

Re-trigger the issue if needed

If you want the orchestrator to retry the issue, re-apply the trigger on the issue. The orchestrator will pick it up on the next poll.
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. This covers both orchestrator-initiated and /ai-implement comment-triggered runs on a repo synced to the current workflow templates; AI_IMPLEMENT_MAX_TURNS on the target repository only has effect on repos still running the older, pre-sync comment-trigger.yml workflow. 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.