Skip to content
CompozyOS RuntimeOperations

Troubleshooting

Diagnose and resolve common Compozy daemon, socket, agent, session, and database issues.

Audience
Operators running durable agent work
Focus
Operations guidance shaped for scanability, day-two clarity, and operator context.

Use this guide when an operational command fails or the daemon is not behaving as expected. Each entry has symptoms, diagnosis, and a resolution path.

Daemon reports "already running"

FieldWhat to check
Symptomscli: daemon already running (pid=12345) or daemon: already running with pid 12345.
DiagnosisThe lock file is held by a live process, or daemon.json points at a process that is still alive.
ResolutionUse the existing daemon, or stop it with compozy daemon stop. Do not remove daemon.lock while the PID is alive.

Inspect the current discovery files:

export COMPOZY_HOME="${COMPOZY_HOME:-$HOME/.compozy}"
compozy status
cat "$COMPOZY_HOME/daemon.json"
cat "$COMPOZY_HOME/daemon.lock"

If the recorded PID is not alive, a new daemon start should acquire the lock, remove the stale socket path, and clean up orphan child processes from the old daemon.

Detached start times out or exits before readiness

FieldWhat to check
Symptomscli: daemon did not become ready before timeout or cli: detached daemon exited before readiness.
DiagnosisThe detached child failed before /api/status became available over UDS. Common causes are invalid config, a port conflict, a socket path conflict, or database open failure.
ResolutionRead the recent log lines, then run foreground mode to see the startup error directly.

Commands:

export COMPOZY_HOME="${COMPOZY_HOME:-$HOME/.compozy}"
tail -n 120 "$COMPOZY_HOME/logs/compozy.log"
compozy daemon start --foreground

Fix the error reported by foreground mode, then start normally:

compozy daemon start

Compozy refuses an incompatible database

FieldWhat to check
SymptomsA daemon-global refusal stops boot and names $COMPOZY_HOME/compozy.db. A per-session refusal can instead appear after Compozy is ready when compozy session history <id> -o json or the HTTP/UDS session-history route opens that session's events.db.
Diagnosislegacy_database means the file predates Compozy's Goose stream. schema_ahead means the recorded Goose version is newer than the running binary. Both refusals leave the incompatible file unchanged; daemon readiness only proves the global and memory streams, not every lazily opened per-session stream.
ResolutionFor schema_ahead, run a newer compatible Compozy binary against the stopped, intact database family—the preferred state-preserving path. For legacy_database, cold-move the complete COMPOZY_HOME or workspace .compozy family and select a separate fresh home. Never edit a version table or move one database/sidecar in isolation.

Stopped-daemon provider-auth, extension, and MCP-auth commands return the same refusal as one structured error document under -o json. Match diagnostic.code as legacy_database or schema_ahead; the diagnostic evidence includes the direct-open surface and canonical offending path.

When a fresh home is the chosen hard-cut path, stop Compozy and preserve the complete old home first:

export COMPOZY_HOME="${COMPOZY_HOME:-$HOME/.compozy}"
compozy daemon stop
legacy_home="${COMPOZY_HOME}.pre-goose-$(date +%Y%m%d-%H%M%S)"
mv "$COMPOZY_HOME" "$legacy_home"
mkdir -p "$COMPOZY_HOME"
compozy daemon start
compozy status -o json | jq '.daemon.schema_streams'

The final command should report the global and memory streams with their applied versions and schema digests. It does not validate every per-session events.db; exercise the affected session-history reader separately. Do not copy legacy tables or session directories into the fresh home. Keep $legacy_home separate for inspection with its matching pre-Goose binary. For schema_ahead, keep the original home in place and use a newer compatible binary instead of this state-discarding path. See Database Operations for cold and live backup rules.

Unix socket cannot be created or opened

FieldWhat to check
SymptomsThe daemon fails with udsapi: existing path ".../daemon.sock" is not a unix socket, or the CLI cannot connect to the daemon socket.
DiagnosisThe configured socket path is occupied by a regular file, or the CLI user cannot read and write the socket. The live socket is chmodded to 0600.
ResolutionStop the daemon, move the non-socket file out of the way, and run the daemon and CLI as the same OS user.

Inspect the socket path:

export COMPOZY_HOME="${COMPOZY_HOME:-$HOME/.compozy}"
socket="$COMPOZY_HOME/daemon.sock"

compozy status
ls -ld "$COMPOZY_HOME" "$(dirname "$socket")"
ls -l "$socket"
file "$socket"

If file "$socket" shows a regular file and the daemon is stopped, move it aside:

mv "$socket" "$socket.stale"
compozy daemon start

If the socket lives outside COMPOZY_HOME, confirm the configured [daemon].socket path and parent directory ownership in config.toml.

HTTP UI or API is unavailable

FieldWhat to check
SymptomsThe browser cannot load http://localhost:2123, or curl cannot connect to the API.
DiagnosisThe daemon is not running, the HTTP port is different, or another process prevented the daemon from binding the configured port.
ResolutionCheck runtime status for the active HTTP host and port. If startup fails from an HTTP bind error, change [http].port or stop the conflicting process.

Commands:

compozy status
curl -s http://localhost:2123/api/status | jq '.daemon'

The default HTTP bind is localhost:2123. For local production use, keep the host on localhost unless you intentionally place Compozy behind a protected reverse proxy.

Agent fails to spawn

FieldWhat to check
SymptomsSession creation fails with an ACP subprocess or initialize error. Logs mention acp: start subprocess, initialize session, command not found, or permission denied.
DiagnosisThe provider command cannot be parsed or executed, the workspace path is invalid, a bound secret is missing, native provider login is absent, or the upstream ACP runtime failed initialization.
ResolutionValidate the agent definition, provider command, auth mode/status, daemon environment, and workspace paths; then restart or recreate the session.

Commands:

compozy agent info <agent-name>
compozy daemon start --foreground
tail -n 120 "$COMPOZY_HOME/logs/compozy.log"
command -v npx
command -v codex
command -v gemini

Agent subprocesses inherit the daemon environment and receive provider credentials from bound credential_slots only when auth_mode = "bound_secret". If a provider uses an env:NAME secret ref, set that variable in the shell or service manager that starts the daemon. If it uses a vault:providers/<provider>/<slot> ref, save the credential through the settings API or web provider editor and confirm the provider status reports the credential as present.

Native ACP providers use their own CLI login/session state. Check them with:

compozy provider auth status <provider>
compozy provider auth login <provider>

compozy provider auth login requires the provider to define auth_login_command. Built-in claude, codex, opencode, and pi providers define one; for custom native providers, configure the command or run the provider's own login command outside Compozy. compozy provider auth login executes the configured login command locally by default and attaches the terminal when stdin, stdout, and stderr are TTYs, so provider prompts and OAuth URLs stay visible. For isolated provider homes, Compozy supplies the required environment prefix so native credentials land in Compozy's provider home. Use compozy provider auth login <provider> --print-command for one raw copyable shell command without executing it, --no-tty for deterministic non-interactive runs, and --timeout when scripts need a bounded attempt. HTTP/UDS and daemon pre-start checks never run login commands; they use non-interactive auth_status_command probes only.

See Spawning for the exact launch and ACP negotiation flow.

Session is stuck after a crash

FieldWhat to check
SymptomsA session appears to stay in starting, active, or stopping after a daemon or agent crash.
DiagnosisThe metadata on disk may describe an in-flight state from a previous daemon process.
ResolutionRestart the daemon, then list or inspect the session. Compozy repairs stale session metadata during boot and session reads.

Commands:

compozy daemon start
compozy session list --all
compozy session status <session-id>
compozy session repair <session-id> --dry-run

The repair rules are:

Stale stateRepaired state
activestopped with stop reason agent_crashed
stoppingstopped with stop reason agent_crashed
startingstopped with stop reason error

For sessions already stopped with agent_crashed or error, boot also repairs interrupted transcripts by appending terminal repair events. If a transcript or chat replay still shows a dangling tool call or streaming assistant message after restart, run:

compozy session repair <session-id> --dry-run
compozy session repair <session-id>

If resume still fails, check that the workspace directory, agent definition, and $COMPOZY_HOME/sessions/<session-id>/events.db still exist.

Database is locked or corrupted

FieldWhat to check
SymptomsSQLite reports database is locked, database disk image is malformed, or the daemon cannot open compozy.db or events.db.
DiagnosisA live daemon may still hold the database, a filesystem copy may have missed WAL sidecars, or SQLite classified the database as corrupt.
ResolutionStop the daemon. Preserve the complete database family byte-for-byte, diagnose a cold copy, and restore a complete known-good family if it is corrupt.

Commands:

export COMPOZY_HOME="${COMPOZY_HOME:-$HOME/.compozy}"
compozy daemon stop
sqlite3 -readonly "/path/to/cold-backup/compozy.db" "pragma integrity_check;"

Compozy does not rename or recreate a database after classifying corruption. For cold backup, family preservation, and restore details, see Database Operations.

Permission errors in COMPOZY_HOME

FieldWhat to check
SymptomsStartup logs show errors creating the home layout, lock file, log file, socket parent, or database directory.
DiagnosisThe daemon user does not own COMPOZY_HOME, or a service manager starts Compozy with a different home path than the CLI.
ResolutionUse one stable COMPOZY_HOME, ensure the daemon user owns it, and run the CLI with the same COMPOZY_HOME when managing that daemon.

Commands:

export COMPOZY_HOME="${COMPOZY_HOME:-$HOME/.compozy}"
ls -ld "$COMPOZY_HOME" "$COMPOZY_HOME/logs" "$COMPOZY_HOME/sessions"
compozy status

For systemd or launchd installs, define COMPOZY_HOME in the service environment and keep provider API keys in the same environment.

On this page