Skip to content

Troubleshooting

Start with the smallest failing boundary: process, API, agent, provider, then channel delivery.

bash
claude-gateway gateway status
claude-gateway doctor
claude-gateway gateway logs --lines 100 --agent assistant
SymptomCheckVerification after the fix
Nothing listensOwning service, bind address, port, startup log/health answers on the intended address
Health works, agent failsWorkspace exists, AGENTS.md, Claude authentication and executableAgent answers a short direct request
Telegram bot stays silentPairing, allowed user, duplicate pollerPaired private chat receives a reply
Telegram group stays silentPrivacy Mode/admin status, group allowlist, mention gateMention produces a reply in the approved group
Discord receives empty messagesMessage Content Intent and channel permissionsBot receives text and answers
LINE webhook rejectedSignature and unchanged raw request bodyA new signed webhook is accepted
MCP tools unavailableBun, MCP dependencies, generated session MCP configA read-only tool returns a real result
API rejects a keyKey value, agent scope, write/admin requirementThe same request succeeds with appropriate scope
Personality unchangedSource workspace files, generated CLAUDE.mdNew turn reflects the edited instructions
Heartbeat did not sendYAML, five-field cron, timezone, rate limit, HEARTBEAT_OKRun evidence and intended channel delivery

Local commands work, public URL fails

A proxy may enforce separate authentication. Compare the address reported by doctor with the intended destination. Local CLI commands normally prefer the running gateway's local address; setting --url deliberately tests another address. gateway.publicUrl must point to this gateway's externally reachable origin for features that generate public links.

Context looks missing

Check that you selected the intended agent, chat, and session. Session persistence and permanent chat history are distinct stores. A missing session file starts a fresh context; do not delete history or configuration as a diagnostic shortcut. See agents and sessions and memory.

Collect a useful report

claude-gateway debug-bundle writes a small redacted diagnostics bundle. Review it before sharing, and include the installed version, failing command or action, expected behavior, actual result, and relevant timestamps. Remove credentials, private messages, and identifying data from manually copied logs.

For ORCHESTRATION_DISABLED or PROFILE_INVENTORY_MISMATCH, inspect the gateway mode and runtime profile using the orchestration guide.

Memory search returns nothing or an old fact

Confirm the search corpus and shared project first. Personal archive sources are MEMORY.md, USER.md, and Markdown under memory/; another workspace document is not automatically indexed. Read the source file to distinguish a missing fact from a stale index. A generated core index is a context optimization and does not mean the full source was erased.

If a note used to be searchable, inspect dreaming and staleness records and whether the source moved or disappeared. For durable archival notes that must survive aging, use the documented memory/pinned/ location. Verify the result by retrieving an exact source excerpt in a new session.

A learned skill is missing or unexpectedly unchanged

Inspect skills/.pending/ when learning runs in propose mode. In auto mode, inspect SKILLS_LEARNED.md and the live SKILL.md. Reaching the tool-call threshold only qualifies a session for review; the daily budget, reviewer outcome, duplicate checks, and provenance guard still apply. A human-authored same-name skill is deliberately protected from automatic overwrite.

For shared skills, edit ~/.claude-gateway/shared-skills/, then verify the managed personal copy and generated menu. Editing only a .shared-marked copy in ~/.claude/skills/ can be undone on the next synchronization.

An app is installed but its URL fails

Read the installation job's terminal state and logs, then inspect the app's declared port name. The proxy path uses the manifest's name, not an arbitrary container port number. Check whether the app is still restoring or reports a boot restoreError. Rebuilds on a fresh Docker host may need longer than a simple restart.

If the app has an agent, check its workspace link, generated agent container, mounted binary paths, and staged Claude configuration. A host login change can refresh the seed without refreshing an already running container's copied configuration. Follow the app lifecycle and backup guide before reinstalling or restoring data.

A schedule fires at the wrong time or after restart

Heartbeats use the process timezone and convert interval shorthand into wall-clock cron. Managed cron jobs default to UTC unless their own timezone is set. Compare the actual schedule type and timezone rather than applying one scheduler's rules to the other.

Managed recurring jobs can catch up missed work after startup; this is capped and does not replay every missed tick. Inspect the prior run timestamp and current run log before manually triggering the job. A missing heartbeat message may instead be a normal rate-limited or HEARTBEAT_OK result.

Source modules for these checks: knowledge indexing, skill writer, app installer, and cron manager.

A task is queued, blocked, or failed

Read the persisted task state before retrying. queued means execution has not started; a progress acknowledgement does not change that. Check per-conversation/per-agent task limits, gateway process capacity, predecessor state, and workspace availability. An after_success continuation whose predecessor failed reports TASK_DEPENDENCY_FAILED; authorized recovery can use an after_terminal continuation with instructions to inspect the existing state first.

ErrorMeaningTargeted check
ORCHESTRATION_DISABLEDThe task path is not enabledGateway-wide orchestration switch
PROFILE_FLAGS_CONFLICTCustom Claude flags conflict with a managed profileRemove conflicting claude.extraFlags; use supported settings
CLI_SKILL_UNAVAILABLENative skill absent from this worker runtimeActual host/container skill inventory
WORKER_GIT_PROJECT_REQUIREDExplicit worktree policy requires a Git projectSelected workspace mode and project root
SHARED_PROJECT_MUST_DIFFER_FROM_IDENTITY_WORKSPACEShared-lock project overlaps identity workspaceUse a separate project directory
CONTAINER_ISOLATION_REQUIREDApp container fails admissionRuntime privileges, namespaces, capabilities, and mounts
ARTIFACT_PATH_DENIEDRequested file is outside the permitted artifact scopeOriginal file location and active task/session ownership

After interruption, inspect current files, remote side effects, and recorded test evidence before retrying the action. A timeout does not establish that edits disappeared or that a deploy failed. Likewise cancel_requested means stopping has been requested; report cancellation only after the terminal cancelled state is confirmed. Stopping a spoken response or chat decision does not cancel ongoing execution tasks.

Source: runtime profile rules, worker driver, and task controls.

Claude Code inside.