Work top to bottom. Most first-run failures are “stack not up”, “wrong Node”, or “API cannot see the CLI / Ollama”. Using the Mac app? Start with Desktop app (macOS). The numbered sections are for a from-source install.

Desktop app (macOS)

The app starts its own database, server and web app, and its start screen tells you which step it is on. Try again restarts only the parts that are not running. You don’t need to quit the app first.

Log files

Show logs opens Finder at the API error log. The other logs sit next to it, except Postgres. Each launch keeps the previous launch’s file with .1 added (for example porto-bundled-api.err.log.1). If the first launch failed and you opened the app again, the first launch’s log is the .1 file. macOS can clear /tmp when the Mac restarts, so copy the logs first if you need them. When you ask for help, attach these files. Read them first and remove anything private.

Ports

The app uses ports 3000 (web app) and 8000 (API) and moves to the next free port when another app already holds one. Its database always uses 54321, 54322 and 54329. If the database step fails, check what holds those ports:

1. Is the API up?

Start Supabase from frontend/: supabase start. Then restart uvicorn.

2. Frontend cannot connect

  • NEXT_PUBLIC_PORTO_WS_URL must match the API (ws://localhost:8000/ws by default).
  • Browser console will show a WebSocket error if the API is down.
  • A production next start build inlines env at build time. After changing .env.local, re-run npm run dev (or rebuild).

3. CLI seat will not spawn

The API must run as that user, with that PATH. Start uvicorn from the same terminal, not from a GUI wrapper with a thin PATH. See CLI harnesses.

4. Local model never answers

  • No listener → start Ollama / vLLM / LM Studio.
  • Listener on the laptop, API in Docker → 127.0.0.1 inside the container is not your laptop. Use a LAN / Tailscale URL, or run the API on the host.
  • First token > 30s on a cold Qwen is normal. porto waits 300s for Ollama and Local / network.

5. Key rejected on Save

porto probes the provider before persist. A 401 from the vendor is a bad key. A timeout is network / wrong base URL. Blank key on edit keeps the stored secret. Blank key on Ollama / Local is allowed.

6. Seat Computer is off

See Computer host and Seat Computer.

7. setup.sh stops on Docker

Start Docker Desktop. Re-run ./setup.sh. The script is idempotent.

8. Node / Python mismatch

Node 20 or 22 only. Python 3.11. nvm use in frontend/ (reads .nvmrc). pyenv local in backend/ (reads .python-version).

9. Ports already bound

10. Encryption key changed

If you rotate PORTO_ENCRYPTION_KEY, old credential rows will not decrypt. Re-save each provider in Settings, or restore the previous key.

Still stuck

  1. cd frontend && supabase status
  2. curl -s http://localhost:8000/readyz
  3. Backend terminal — look for structured logs (adapter_invoked, provider_error), not a Python traceback you have to guess.
Do not paste service-role keys or API keys into a chat when you ask for help. Redact them.