Troubleshooting
Common self-host failure modes and what they mean.
Most self-host issues fall into one of a few buckets. Diagnose by checking, in order: webhook delivery → API logs → worker logs → Temporal UI.
Webhooks never arrive
Symptoms: ticket assigned to agent, but no Linear comment appears, no PR is opened, API logs show no webhook activity.
Check, in order:
- Public URL is reachable.
curl https://<APP_BASE_URL>/healthzfrom outside your network. Should return200 OK. If it returns530, the tunnel/ingress is down. - Webhook URL on the App is correct. GitHub: App settings → Webhook → URL. Linear: App settings → Webhooks. Should be
<APP_BASE_URL>/webhooks/githuband<APP_BASE_URL>/webhooks/linear. - Recent deliveries — both providers show delivery history. A 4xx means Sinatra rejected it. A 5xx means it crashed. A timeout means it never reached the API.
- cloudflared QUIC issues: if cloudflared logs
failed to dial to edge with quic: timeout, force HTTP/2 with--protocol http2.
Webhooks arrive but signature verification fails
Symptoms: API logs show 401 responses to webhook deliveries.
The webhook secret in your env doesn't match the one set on the App.
- For GitHub:
GITHUB_APP_WEBHOOK_SECRETmust equal the secret in App settings → Webhook. - For Linear:
LINEAR_WEBHOOK_SECRETmust equal the Webhook signing secret shown on the Linear App page.
Regenerate the App-side secret if you've lost track of it.
Workflow starts but never progresses past pending
Symptoms: Temporal UI shows a workflow stuck in pending or fails immediately.
- Worker not running — check
pnpm dev:worker(dev) or your worker process status. - Worker can't reach Temporal — check
TEMPORAL_ADDRESSmatches what the dev server / Temporal Cloud is on. - Worker can't reach Postgres — check
DATABASE_URLfrom the worker host.
Sandbox creation fails
Symptoms: workflow crashes early in the agent step. Worker logs mention sandbox creation.
For SANDBOX_PROVIDER=daytona:
DAYTONA_API_KEYis missing or invalid.- The snapshot named in
.sinatrarc.sandbox.snapshot_name(defaultsinatra-agent) doesn't exist in your Daytona account. Sinatra will create it on first run; if it didn't, check the logs for4xxfrom Daytona.
For SANDBOX_PROVIDER=docker:
- The local
dockerdaemon isn't running. - The
sinatra-agent(orsinatra-agent-base) image isn't built locally. Build them perdocs/local-development.md. git clonefails because the GitHub App installation token wasn't generated correctly — see "GitHub App private key formatting" below.
"Invalid GitHub App private key"
The PEM in GITHUB_APP_PRIVATE_KEY got mangled. The fix is always: paste the full PEM (including -----BEGIN/END----- lines) wrapped in double quotes in the env file:
GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIE...
-----END RSA PRIVATE KEY-----"If you lose the original, regenerate one in App settings → Private keys → Generate a private key.
Agent runs but fails to commit / push
Symptoms: workflow logs show the agent did work, but the PR never appears.
- The GitHub App isn't installed on the target repo. Go to App settings → Install App and add the repo.
- The agent's
gh authwas disrupted by host env vars. Run with a clean env (noGH_TOKEN/GITHUB_TOKENset in your shell).
Anthropic 401 / "model credential invalid"
Symptoms: classifier or agent calls fail with a typed ModelCredentialInvalid error.
- For
SANDBOX_PROVIDER=docker: the hostclaudeCLI isn't logged in. Runclaude loginand retry. - For
SANDBOX_PROVIDER=daytona: there's notenantModelCredentialrow for your tenant, or its KMS-encrypted ciphertext can't be decrypted (wrongSINATRA_KMS_KEY?). Seedocs/debugging.mdStage 5 in the contributor docs for the seeding script.
I'm still stuck
Open an issue in the repo with:
- The 9-step you got to before things broke.
- The relevant log excerpt (API and worker).
- A redacted snippet of your
.env.productionshowing the variables that are set (not the values).
Most of the bumps are env-var typos and webhook URL mismatches.