Skip to content

Troubleshooting

A directory of the most common problems and their fixes.

Install / setup

Set JWT_SECRET in docker/.env

The Docker compose file refuses to start without the three required secrets.

JWT_SECRET=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
INTERNAL_SECRET=$(openssl rand -hex 32)

cat >> docker/.env <<EOF
JWT_SECRET=$JWT_SECRET
ENCRYPTION_KEY=$ENCRYPTION_KEY
INTERNAL_SECRET=$INTERNAL_SECRET
EOF

Or just re-run ./deployment/docker/setup.sh; it generates them automatically.

pnpm install fails on Windows

Make sure you have:

  • Node.js 22 (not 18 / 20). Run node -v.
  • Visual Studio Build Tools or windows-build-tools for native modules.
  • Long path support enabled (git config --system core.longpaths true).

pnpm db:migrate errors with "extension pgvector not found"

Your PostgreSQL doesn't have pgvector. On Ubuntu:

sudo apt install -y postgresql-16-pgvector

Or use the bundled Docker Postgres which has it preinstalled:

docker compose -f docker/docker-compose.yml up postgres -d

Runtime

502 Bad Gateway from Caddy

The API container is still booting (10-30 seconds on first start). Check:

docker compose -f deployment/docker/docker-compose.yml logs api | tail -50

If you see a Postgres connection error, the migrate container hasn't finished. Wait, then refresh.

Browser shows a Caddy welcome page

deployment/docker/setup.sh didn't render the Caddyfile for your domain. Re-run it with the right DOMAIN= and EMAIL= and check the in-stack Caddy container logs.

Browser shows a self-signed certificate warning

Expected when:

  • You used ./deployment/docker/setup.sh without a domain.
  • You used HOST=192.168.x.x ./deployment/docker/setup.sh.
  • You're running on localhost.

Either accept the warning, or import /etc/ssl/doable/cert.pem into your OS/browser trust store. For a real cert, deploy with DOMAIN=....

ECONNREFUSED ::1:4000 from the web app

Node's resolver picked IPv6 first. Make sure your .env uses 127.0.0.1, not localhost:

NEXT_PUBLIC_API_URL=http://127.0.0.1:4000

Live preview is blank

Open the preview iframe URL directly in a new tab. Possible causes:

  • The project's Vite dev server crashed; check services/api logs for [dev-server] lines.
  • A build error blocks the page; open the editor's preview pane to see the error overlay.
  • The visual edit bridge couldn't be injected (rare; see Visual Edit).

Restart the dev server: editor toolbar, then Run.

Real-time collaboration not syncing

  • Check that services/ws is running (docker compose ps ws, or tmux attach -t doable window 2).
  • Check NEXT_PUBLIC_WS_URL matches the actual WS URL: ws:// for HTTP, wss:// for HTTPS.
  • The reverse proxy must forward the Upgrade: websocket header. nginx config snippet:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

"No AI provider configured" in chat

  • Confirm at least one of ANTHROPIC_API_KEY, OPENAI_API_KEY, COPILOT_CLI_PATH, COPILOT_CLI_URL is set in the API process's environment.
  • Restart after editing .env: docker compose restart api or systemctl restart doable.
  • If using Copilot CLI, run it once interactively to verify auth: copilot auth status.

Chat hangs without streaming

  • Check the browser network panel: the /chat/.../messages request should be text/event-stream. If it's application/json, the request never reached SSE, usually a proxy buffering issue.
  • nginx: add proxy_buffering off; for /chat and /plan locations.

Out of disk

PROJECTS_ROOT grows over time as more projects are created. Clean up:

# Find the largest projects
du -sh /path/to/projects/* | sort -h | tail
# Delete soft-deleted projects with no recent activity
psql -c "SELECT id FROM projects WHERE deleted_at < now() - interval '90 days'"
# (Then rm the matching directories.)

For Docker, the api_projects volume: docker volume inspect doable_api_projects.

Out of memory during build

Symptoms: pnpm build killed, JavaScript heap out of memory.

  • Add swap (the bare-metal installer adds 2 GB by default).
  • Increase Node's heap: NODE_OPTIONS=--max-old-space-size=4096 pnpm build.

AI

Permission prompt for every tool call

Your workspace policy is too strict (set to "ask" for many tools). Tighten or relax it from Workspace Settings, AI, Tools.

credit_exhausted for everyone

The workspace's AI credit balance is at 0. Either:

  • Top up via Stripe (if billing is enabled), or
  • Disable Stripe to remove the limit, or
  • Adjust the limit from Workspace Settings, AI, Limits (admin).

Anthropic / OpenAI 429 rate limit

Doable retries automatically, then surfaces the error. Solutions:

  • Bump your provider plan.
  • Configure a fallback provider order in workspace settings.
  • Reduce parallel chats.

Database

too many connections on PostgreSQL

DATABASE_POOL_SIZE x number_of_processes exceeds Postgres' max_connections. Lower DATABASE_POOL_SIZE (default 20) or raise Postgres' limit.

Slow queries

psql -c "SELECT pid, now() - query_start AS dur, query
         FROM pg_stat_activity
         WHERE state = 'active' ORDER BY dur DESC LIMIT 20;"

The frequent culprit is the analytics rollup queries. Check the schedule in services/api/src/analytics/.

Deployment

cloudflared connection failures

journalctl -u cloudflared -e

Common: cert expired (cloudflared tunnel login to renew); tunnel deleted in Cloudflare console.

Caddy not auto-issuing SSL

Check journalctl -u caddy -f while loading the site for the first time. Common causes: DNS doesn't resolve to the host, port 80 isn't reachable from Let's Encrypt, ACME rate limit hit.

For Cloudflare Tunnel deployments, Caddy can still get a cert because it issues via DNS-01 if you add the Cloudflare DNS plugin, or you let Cloudflare provide the public-facing cert and Caddy serves on HTTP internally.

Still stuck?

  • Check the GitHub Issues.
  • Search the GitHub Discussions.
  • File a new issue with: deployment mode, OS, the exact error, the relevant log snippet, and the steps you took.