# Troubleshooting COMA

Start with `coma doctor --json`; it exits 10 when a check fails and always writes the report to stdout. Full guide: https://coma.sh/docs/guides/troubleshooting

## Containers ran on the laptop instead of the machine

Something sent Docker commands to a local engine. Usual causes:

- `DOCKER_HOST` or `DOCKER_CONTEXT` is set in the shell; either overrides the `coma` context. `coma connect` warns about both.
- `docker` is an alias for podman while connected to a Docker engine. The fix is `coma connect <machine> --engine podman`.
- A tool replaced `DOCKER_CONFIG`, which also drops the `coma` context. Coding agents do this to work around a missing credential helper. Don't.

`coma doctor --json` reports containers created on local engines in `local-fallback`, with the latest name, image and time. `coma daemon logs --json` lists each one. Fix the cause, then `docker context show` should print `coma`.

## Every image pull fails

Docker's `config.json` names a credential helper that is not installed (often `"credsStore": "osxkeychain"` left over from Docker Desktop). `coma doctor` reports it in `docker-credentials`. The user should remove `credsStore`/`credHelpers` or install the helper. Ask before editing `~/.docker/config.json`.

## docker compose cannot read compose.yaml

Compose v1 is first on PATH. Agent shells can order PATH differently from the user's terminal. `coma doctor` lists every Compose v1 in `docker-compose`. Use `docker compose` (v2); suggest removing the old `docker-compose`.

## localhost reaches the wrong service, or "local port in use"

`coma port list --json` shows each port's state. `local port in use` means a program on the laptop already listens there (a local database, Docker Desktop, a Podman machine). Stop it, or declare the port at another local number in `coma.yaml`:

```yaml
spec:
  ports:
    - remote: 5432
      local: 15432
```

## A bind mount is refused

- `sync_bind_source_unmanaged`: outside every synced directory. Use the workspace, or `coma sync watch --path <dir> --json`.
- `sync_bind_source_missing`: ignored by sync. `coma sync explain <path> --json` says which rule.
- `sync_barrier_timeout`: latest changes had not arrived. `coma sync status --json`, then retry.

## A file is in conflict

`one-way-safe` never overwrites a file changed on the machine; a file changed on both sides keeps the machine's copy. `coma sync status --json` names each file. Ask which copy wins, then `coma sync resolve <path> --keep local` (yours to the machine) or `--keep machine` (the machine's to the laptop). Files both a container and a local run write, such as `__pycache__/`, belong in `.gitignore` or `.comaignore`.

## Docker commands fail after sleep or a network change

comad reconnects on its own; no need to reconnect. Clients wait up to 10 s, then get an error naming the machine and reason. After 5 failures in a row the endpoint shows `degraded` and COMA keeps retrying. A changed host key or a refused SSH login stops retries until the next `coma connect`. Check `coma endpoint list --json` and `coma daemon logs --json`.

## coma connect: a Docker context named coma already exists

`docker_context_conflict`: a `coma` context exists that COMA did not create. Ask before `coma connect --replace`.

## coma workspace up is blocked

- `workspace_plan_blocked` with `bidirectional`: only the user can opt in. Tell them.
- `confirmation_required`: `one-way-mirror` deletes and overwrites files on the machine on first sync. Ask before `--yes`.
- `sync_mode_unsupported`: the opt-in modes need Mutagen. Check `sync-helper` in `coma doctor --json`.

## Ctrl-C returned but the container still runs

COMA forwards the interrupt; a main process that ignores it keeps running, as on a local engine. Stop it with `docker stop`, and use `docker run --init` for commands you may interrupt.

## Codex: socket denied or ~/.docker not writable

Codex's `workspace-write` sandbox blocks Unix sockets outside the workspace (including COMA's) and writes to `~/.docker`. Codex may then fall back to a project-local `DOCKER_CONFIG` and a local engine. The user should set `sandbox_workspace_write.network_access = true` and add `~/.docker` to `sandbox_workspace_write.writable_roots`, or approve the escalation. Do not work around it.

## Inspect one endpoint

Endpoints are named `<machine>-<engine>`; states are `ready`, `reconnecting`, `degraded`, `stopped`.

```bash
coma endpoint list --json
coma endpoint doctor dev-docker --json
coma endpoint doctor dev-docker --explain-last --json
```

`--explain-last` shows the last container request COMA handled: forwarded or refused (and why), ports moved to `127.0.0.1`, `-P` expanded, bind sources mapped to the synced copy, the Docker socket mapped, a start held for port mirrors. Request bodies are never shown.

## Logs

`--verbose`, `--debug` and `--trace` log to stderr; stdout stays one JSON document with `--json`. comad's log: `coma daemon logs --lines 100`. `coma daemon status --json` says whether comad runs and where its log is.
