Sinatra Docs
Self-hosting

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:

  1. Public URL is reachable. curl https://<APP_BASE_URL>/healthz from outside your network. Should return 200 OK. If it returns 530, the tunnel/ingress is down.
  2. Webhook URL on the App is correct. GitHub: App settings → Webhook → URL. Linear: App settings → Webhooks. Should be <APP_BASE_URL>/webhooks/github and <APP_BASE_URL>/webhooks/linear.
  3. 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.
  4. 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_SECRET must equal the secret in App settings → Webhook.
  • For Linear: LINEAR_WEBHOOK_SECRET must 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_ADDRESS matches what the dev server / Temporal Cloud is on.
  • Worker can't reach Postgres — check DATABASE_URL from 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_KEY is missing or invalid.
  • The snapshot named in .sinatrarc.sandbox.snapshot_name (default sinatra-agent) doesn't exist in your Daytona account. Sinatra will create it on first run; if it didn't, check the logs for 4xx from Daytona.

For SANDBOX_PROVIDER=docker:

  • The local docker daemon isn't running.
  • The sinatra-agent (or sinatra-agent-base) image isn't built locally. Build them per docs/local-development.md.
  • git clone fails 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 auth was disrupted by host env vars. Run with a clean env (no GH_TOKEN/GITHUB_TOKEN set in your shell).

Anthropic 401 / "model credential invalid"

Symptoms: classifier or agent calls fail with a typed ModelCredentialInvalid error.

  • For SANDBOX_PROVIDER=docker: the host claude CLI isn't logged in. Run claude login and retry.
  • For SANDBOX_PROVIDER=daytona: there's no tenantModelCredential row for your tenant, or its KMS-encrypted ciphertext can't be decrypted (wrong SINATRA_KMS_KEY?). See docs/debugging.md Stage 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.production showing the variables that are set (not the values).

Most of the bumps are env-var typos and webhook URL mismatches.