-
Notifications
You must be signed in to change notification settings - Fork 0
troubleshooting
github-actions[bot] edited this page Sep 22, 2026
·
16 revisions
| Symptom | What to do |
|---|---|
gcloud not installed |
Install the Cloud SDK only if you need Google identity. Local-only services still run |
| ADC unavailable |
/auth login or gcloud auth application-default login, then devctl auth status / /auth refresh
|
| Wrong project | Set google.project_id or check gcloud config get-value core/project. Identity shows the source |
| Permission denied | Ask an admin for the missing IAM role; devctl doctor names the resource |
| Cannot impersonate SA | Need roles/iam.serviceAccountTokenCreator on that service account (group binding preferred) |
| IAP authentication failure | Confirm audience, IAP client, and that the identity matches the route. If client_id is set, the ADC refresh token must belong to that OAuth client |
| Port already in use | Doctor lists the holder. Stop a leftover, or change config. Running your own services will also show as “in use” |
| Service crashes | Open Logs, filter ERROR (e), restart with R
|
| Health check failure | Confirm the health URL/port; tcp is connect-only; grpc is Health/Check (SERVING); process checks only PID liveness |
| Proxy unavailable / missing listen port | Pin proxy.listen.port (required when proxy.enabled is true — validate exits 2). Then devctl proxy start or TUI n. Starting with port 0 exits 7. Bind is loopback only |
| Token expired | Automatic refresh uses auth.refresh_threshold_seconds; run devctl auth refresh. Open Doctor if ADC itself expired |
| Token audience incorrect | Set auth.audience on the IAP route; Doctor flags missing audiences |
| IAP used a user token for an SA route | Confirm the route identity is service_account; Doctor probes impersonated IAP separately |
| Leftover process after crash | Reopen devctl — adopt when the pid is alive and the command matches ~/.devctl/state/<hash>/state.json. A start time that only drifted (sleep, WSL clock) still matches; a newer process on that pid does not. A port with no persisted pid is never attached |
devctl attach fails |
No supervisor. Use devctl start first; attach never starts one |
devctl status looks empty |
If the socket is down, status prints persisted state and exits 0 when nothing is running. The TUI still starts a supervisor; leftover PIDs from the previous session appear on the idle dashboard |
| Start exits 5 or 6 | 5 = spawn failed; 6 = health never passed. Doctor then Logs |
start brought up extra services |
Empty start uses the active or first profile alphabetically — YAML key order does not matter (demo: backend, not data). A profile start no longer pulls omitted dependencies. Named devctl start invoices-api (no profile) still expands the local closure |
| Docker / Podman missing or daemon down | A service in config declares container (the demo's postgres always does, even if you never start data). Install and start that runtime, or drop the service. Default profiles do not start postgres |
| Doctor offers to kill a busy port that is Docker | It should not: ports owned by a running container service are healthy, and Doctor never offers to terminate the Docker or Podman daemon. Re-run Doctor after the container is up |
| MCP tools work but nothing starts |
get_status reports setup_mode: true — there is no .devctl yet. Have the agent call get_setup_guide, search_docs, and validate_config, write the files, then reload_config
|
devctl exec --print-env hides values |
Secret-like names are redacted unless you also pass --reveal (TUI: /exec <svc> --print-env --reveal or /reveal). MCP exec_service never reveals them |
| TUI env pane looks incomplete | It now loads the same resolved map as devctl exec --print-env. If the chip says config fallback, the daemon exec call failed — check /daemon and that the supervisor is up |
TUI says Configuration error but devctl config validate is clean |
The supervisor failed to start (often EADDRINUSE). The TUI now shows Supervisor failed to start with the bootstrap-log line. devctl daemon logs has the same text |
| Supervisor will not start |
devctl daemon logs or TUI /daemon is the bootstrap stderr, not the service log bus. unable to listen … (EADDRINUSE) means a leftover already holds that port — Doctor names the holder |
| TUI stale / not updating | TUI follows the event bus (20–50ms batch). Quit and let a new supervisor start if an old one is still listening |
status or logs_page timed out after 30000ms after sleep, and restart or quit hangs |
Common after a Windows sleep while devctl runs in WSL or a VS Code dev container. Quit returns without waiting on the dead connection. Start again: an unresponsive supervisor is replaced and services that are still listening are adopted |
| Reload needs a restart |
devctl reload and /reload list services whose command, env, ports, or identity changed |
| Configuration invalid |
devctl config validate — unknown fields, cycles, and missing refs fail closed. TUI v / /buffer validates before write |
| Config on disk is broken but the TUI still opens fine | Expected: it attached to an already-running daemon and is showing its config_snapshot (last-known-good), not a fresh reparse of the broken file. Fix the file and /reload
|
devctl update says unavailable |
GitHub Releases API could not be reached. For npm: npm install --global @amr-m-abdelgawad/devctl@latest. Homebrew and GitHub binaries: see installation
|
| MCP agent cannot connect | Listener is off by default. /mcp or devctl mcp --on. URL is loopback only; snippets include the bearer token |
Web UI shows {"error":"forbidden"}
|
The page Host header was not a loopback name. Use the printed http://127.0.0.1:<port>/ (or localhost / [::1]), not a machine or Dev Container hostname. 0.8.0 required the Host port to match exactly, so WSL / Dev Container port forwarding and IPv6 localhost 403'd; upgrade to 0.8.1 |
devctl: command not found |
Run npm install --global @amr-m-abdelgawad/devctl, then ensure npm's global binary directory is on PATH. See Installation
|
| Bundled Bun runtime was not installed | Reinstall the npm package without --ignore-scripts; Bun uses its install script to select the correct platform runtime |
Internal devctl logs appear in the Logs screen with source devctl.
Start
- How it fits together
- Installation
- Quick start
- Onboard your repository
- Examples & recipes
- Developer setup
- Agent skills
Use
Configure
Identity
Reference