crewship doctor
Runs a battery of checks against the local Crewship install and prints one row per check with a status. Designed for the “is everything OK before I file an issue?” workflow.Exit codes
WARN does not fail the command — you can wire
crewship doctor
into a healthcheck without false alarms on transient external state
(e.g. Sentry endpoint briefly unreachable). FAIL means a core
requirement for starting Crewship is missing or broken; treat the
non-zero exit as a hard gate.
Check categories
Server-dependent checks (server reachable, episodic recall mode, cli server scheme) resolve the same effective server other commands dial:--server flag →
active profile (--profile / CREWSHIP_PROFILE) → CREWSHIP_SERVER env → config.
An active profile that has no server: entry fails closed — the scheme check reports
INFO instead of silently diagnosing a different host than your API calls use.
Container runtime
Detects which Docker-compatible runtime is available — Docker, Podman, Colima, OrbStack, Apple Containers, or Rancher Desktop. Auto-probes each candidate socket; the first reachable one wins.- PASS — runtime detected; agents can run.
- FAIL — no runtime found. Install one; see Install — container runtime requirement.
Port binding
Confirms the HTTP port (default8080 or CREWSHIP_PORT) is free.
- PASS — port is bindable.
- FAIL — port in use.
lsof -i :8080to find the squatter, or changeCREWSHIP_PORT.
Database file permissions
Stats~/.crewship/ directory and the SQLite DB file. Expects:
- Parent directory:
0700 - DB file:
0600 - WAL + SHM sidecars (if present):
0600
tar without
preserving mode bits. Fix:
NEXTAUTH_SECRET
Surfaces where the JWT signing secret lives (env var vs<dataDir>/secrets.env) and validates the value is at least 32 characters. As of PR #446 the secret is auto-bootstrapped on first start, so a missing value is no longer a failure — doctor reports INFO and the next crewship start generates it.
Episodic recall mode
Reads theepisodic field from the running server’s /healthz.
Reports whether episodic memory recall runs
with a vector embedder or degraded to keyword/FTS only.
- PASS —
vector + sparse recall— an embedder is configured (KEEPER_OLLAMA_URL); the boot-time indexer sweeper is embedding journal entries and recall serves vector + BM25 results. - FAIL —
vector-degraded— an embedder is configured but its calls are failing, so the index is not growing and recall is silently BM25-only. The server includes the underlying error asepisodic_errorand this check prints it. The usual cause is an Ollama host that is reachable but not serving the model —ollama pull nomic-embed-texton that host. This is a FAIL rather than a WARN because it is worse thansparse-only: that one is a deliberate choice that still serves keyword recall, whereas this looks configured and delivers nothing. - WARN —
sparse-only— no embedder configured. Recall still works on keywords, but vector similarity is off. SetKEEPER_OLLAMA_URLto an Ollama host servingnomic-embed-text. - INFO — server not reachable / older server — the daemon is down
(the server reachable check already FAILs for that) or predates
the
episodichealth field.
Legacy crew resources
Calls the authenticatedGET /api/v1/admin/legacy-resources endpoint to detect
orphaned pre-C1 (slug-only) crew docker resources that survive
crewship seed --nuke and make every agent in the affected crew fail to start
— surfaced to users only as a generic “failed to start agent container”.
(Detection runs on this admin endpoint rather than the unauthenticated
/healthz path, so a slow docker daemon can’t stall health probes.)
- PASS —
clean— no orphaned legacy volumes/containers for any current crew slug. - WARN —
present— at least one orphaned pre-C1 resource exists. Agents in the affected crew(s) will fail to start. Runcrewship admin prune-legacyto remove them. - INFO — not logged in / unreachable / non-docker server — the check needs
an authenticated session (
crewship login); or the daemon is down (the server reachable check covers that) or the container provider isn’t docker.
Telemetry status
Readsapp_settings.telemetry_opt_in from the local DB. Reports:
- PASS — ENABLED + DSN — telemetry is on and a DSN is wired in.
Shows the endpoint host (vendor default vs
CREWSHIP_SENTRY_DSNoverride). - PASS — DISABLED — operator opted out via
crewship telemetry off. - WARN — ENABLED but no DSN — consent recorded but no DSN available. Local dev builds without ldflag injection; not an error, just informational.
- WARN — not configured — fresh DB, never asked. Will default to
ENABLED on the next
crewship start(v0.1 beta behaviour).
DSN reachability
Only runs when telemetry is enabled AND a DSN is set. Best-effort TCP connect (5s timeout) to the resolved endpoint at port 443.- PASS — endpoint reachable; events will ship.
- WARN — endpoint unreachable. Crashes won’t ship until network
heals. Not a Crewship health signal — could be local firewall, DNS
issue, or Sentry outage.
crewship doctordoes not fail on this; you’d be silently angry at the wrong layer.
Update available
Calls the GitHub Releases API for the project (cached 24h locally).- PASS — running latest stable, or running a newer pre-release.
- WARN — newer stable available; output shows current → latest
with install hint (
brew upgrade crewshipordocker pull). - INFO — running a dev build, version check skipped.
CREWSHIP_SKIP_UPDATE_CHECK=1.
Example output
PR #441 added a version + OS/arch header banner and a “Next steps” footer that points the operator at the three commands that actually move them forward (or at the troubleshooting page on FAIL). Presentation-only — no check behaviour changes.Output formats
--no-color— disable ANSI colors. Auto-detected when stdout is not a TTY (so log-collection scripts get plain text without any flag).- Status codes (
PASS/WARN/FAIL/INFO) are always in left-padded brackets and parseable withawk '{print $1}'.
Auto-repair (--fix)
--fix opts into safe, narrowly-scoped repair side-effects during the
check run. Currently scoped to:
- Database directory missing — creates
$CREWSHIP_DATA_DIR(or~/.crewship) with0700perms instead of failing the check. The detail column then reads(created via --fix)so you can see what changed.
--fix is
for first-run onboarding, not running surgery on a populated install.
When to run
- Before opening a GitHub issue — attach
crewship doctor --no-coloroutput. Saves a back-and-forth diagnostic round. - After upgrading the binary — pre-migration snapshot has run by this point; doctor confirms the new binary is happy with the existing DB.
- In CI smoke tests — the
.github/workflows/smoke-test.ymlworkflow runscrewship doctoragainst the freshly-released binary on each release tag to catch broken binaries before they reach users.
Related
crewship start— the command doctor is checking for. If doctor is green,startshould succeed.crewship telemetry— flip consent state that doctor reports.crewship version— same version info doctor uses for the update-availability check.- Troubleshooting — symptom-keyed catalog of common failures.