24 KiB
24 KiB
OpenClaw Troubleshooting & Incident Playbook
This document captures fixed issues, operational quirks, and incident root-cause analyses for the OpenClaw deployment on Kubernetes.
Important
Rule for Agents & Operators: Whenever you fix a bug, diagnose an operational failure, or resolve a configuration pitfall in OpenClaw, document it here immediately. This prevents recurring regressions and serves as the single source of truth for troubleshooting.
📋 Catalog of Incidents & Fixed Issues
| Date | Category | Summary / Symptom | Status | Key Resolution |
|---|---|---|---|---|
| 2026-09-20 | Timeout & Execution | Telegram #IT Guy (Topic 119) and #Recherche (Topic 117) request timed out before response generated (timeoutSeconds exceeded) |
RESOLVED |
Raised global agents.defaults.timeoutSeconds from 600 to 1800 (30 min). |
| 2026-09-20 | Config Schema Validation | Pod crash with CrashLoopBackOff: agents.entries.<id>: Unrecognized key: "timeoutSeconds" |
RESOLVED |
timeoutSeconds is strictly global under agents.defaults.timeoutSeconds; do not place it under agents.entries.*. |
| 2026-09-24 | Database & Startup Latency | Gateway crash/restart during initialization: slow OpenClaw agent database open leading to Startup/Liveness probe failures |
RESOLVED |
Raised startup probe threshold to 240 (20 min) and checkpointed WAL across subagent SQLite databases. |
| 2026-09-28 | Security & Workspace Files | Subagents rejected bootstrap files on every turn: bootstrap file is unreadable: ... reason=path must not be hardlinked |
RESOLVED |
Decoupled USER.md and MEMORY.md into standalone copies (nlink == 1) across all subagent workspaces via cp --remove-destination. |
| 2026-09-28 | Cron Trigger Scope | Website watch cron job failed: cron trigger evaluation failed (internal_error): ReferenceError: state is not defined |
RESOLVED |
Guarded against undeclared state in JavaScript trigger sandbox via typeof state !== 'undefined' && state. |
| 2026-09-28 | Token Saturation & Model Degradation | Subagents emitted hallucinatory slang/jargon (e.g. Hebamme with Sleep-Hax0r) and Node.js event loop delayed 31s under 2GB RSS |
RESOLVED |
Identified uncompacted 127k-token sessions causing reasoning collapse in GLM-5.3-Flash. Compacted live bloated sessions and automated multi-agent nightly compaction via setup-compaction-cron.sh. |
| 2026-09-29 | Hardlink Regression & Disk I/O | Pod crashed with SIGKILL (137), bot unresponsive, startup stuck in Dl state opening agent SQLite DBs |
RESOLVED |
Replaced recurring ln -f in cronjob-wiki-backup.secret.yaml with cp --remove-destination, decoupled live workspace files, warmed Linux page cache for 12 agent DBs on HDD storage, restoring 5/5 Running. |
| 2026-09-29 | Compaction Pitfall & Split-Turn Drift | Shopping agent ignored user message (Küchenwaage) and replied with old supermarket wiki edit in broken German | RESOLVED |
Identified --max-lines 250 bypassing LLM compaction on sessions with <250 lines but 40k-95k tokens. Switched to true LLM summarization, compacted live sessions, added event-loop pacing, and documented split-turn context recovery. |
| 2026-09-29 | Audio & Speech-to-Text | Telegram voice notes failed transcription with reason=ProviderHttpError, passing empty text (0 chars) and inducing bot hallucinations |
RESOLVED |
Identified OpenRouter audio balance floor ($0.50) causing HTTP 402 when key quota was within $0.50 of monthly limit. Topped up buffer, verified transcription, and switched Recherche agent to DeepSeek V4.1 Flash. |
🔍 Detailed Incident Records
Issue 1: Telegram Agent Request Timeout (agents.defaults.timeoutSeconds)
- Date: 2026-09-20
- Severity: High (User-facing timeout in Telegram topics
#IT Guyand#Recherche) - Symptom:
Telegram replies with error message:
Request timed out before a response was generated. Please try again, or increase agents.defaults.timeoutSeconds in your config. - Root Cause:
The IT Guy agent (
itguy) performs deep, sequential DevOps investigations (multipleexec/kubectlcalls, file writes, and PR operations) usingdeepseek/deepseek-v4.1-flash. Similarly,#Rechercheruns deep research chains. The global default was set totimeoutSeconds: 600(10 minutes), causing active, non-stuck runs to be killed mid-flight. - Resolution:
In
k8s/openclaw/openclaw-instance.secret.yaml, configure:spec: config: raw: agents: defaults: timeoutSeconds: 1800 # 30 minutes - How to Avoid Recurrence: Always verify timeout requirements against the longest-running task types (multi-step K8s audits and deep research). Never assume 10 minutes is sufficient for multi-turn tool loops.
Issue 2: Schema Crash on Per-Agent Timeout Override
- Date: 2026-09-20
- Severity: Critical (Deployment blocked with
CrashLoopBackOff) - Symptom:
Gateway container fails during startup:
Gateway failed to start: Invalid config at /home/openclaw/.openclaw/openclaw.json: openclaw.json:169 — agents.entries.itguy: Unrecognized key: "timeoutSeconds" - Root Cause:
OpenClaw’s JSON schema strict validator does not permit
timeoutSecondsinside individual agent entries underagents.entries.<name>. - Resolution:
Remove
timeoutSecondsfromagents.entries.*. Configure it strictly at the root ofagents.defaults.timeoutSeconds. - How to Avoid Recurrence:
Before adding new keys to agent configurations in
openclaw-instance.secret.yaml, inspect the upstream OpenClaw schema or test locally to ensure the key is recognized under that exact path.
Issue 3: Startup Probe Failures due to Slow SQLite Database Initialization
- Date: 2026-09-24
- Severity: High (Intermittent container kills on gateway restart)
- Symptom:
Container
openclawfails startup or liveness probes, causing kubelet to restart the container:Logs display repeated warnings:Liveness probe failed: Get "http://...:18790/healthz": context deadline exceeded Startup probe failed: context deadline exceeded / connection reset by peer[state/agent-db] slow OpenClaw agent database open - Root Cause:
OpenClaw maintains separate SQLite databases for each specialist subagent (
agents/*/agent/openclaw-agent.sqlite). Over time, databases and uncommitted WAL logs accumulate significant size:agents/main/agent/openclaw-agent.sqlite: >220 MBagents/fitness/,agents/itguy/,agents/hebamme/,agents/recherche/: >100 MB each + multi-megabyte WAL files. On startup, SQLite WAL recovery and integrity passes across 10+ databases on single-node hostpath storage can take several minutes. If this exceeds thestartupProbelimit (failureThreshold * periodSeconds), Kubernetes kills the container before it finishes opening databases.
- Resolution:
- Increase
probes.startup.failureThresholdinopenclaw-instance.secret.yamlto 240 (with 5s period = 1200s / 20 min). - Periodically run
PRAGMA wal_checkpoint(TRUNCATE)across all SQLite databases to compact WAL journals into main files.
- Increase
- How to Avoid Recurrence:
Monitor SQLite database sizes under
/home/openclaw/.openclaw/agents/*/agent/and avoid overly aggressive liveness/startup probe kill thresholds during gateway initialization.
Issue 4: Bootstrap File Rejection due to Inode Hardlink Security Boundary
- Date: 2026-09-28
- Severity: High (Subagents lose access to user profile and memory context)
- Symptom:
On every message turn directed to subagents (e.g. Hebamme, Koch, IT Guy), the gateway log reports:
[workspace] bootstrap file is unreadable: file=/home/openclaw/.openclaw/workspace-<subagent>/USER.md reason=path must not be hardlinked [workspace] bootstrap file is unreadable: file=/home/openclaw/.openclaw/workspace-<subagent>/MEMORY.md reason=path must not be hardlinked - Root Cause:
OpenClaw’s embedded execution harness enforces a strict filesystem security check:
stat.nlink > 1triggerspath must not be hardlinked. This prevents cross-agent symlink/hardlink inode attacks or unauthorized file modification. An earlier optimization created hardlinks between the main workspace and subagent workspaces, causing all subagents to reject the bootstrap files. - Resolution:
Decouple all hardlinked files so that each workspace has its own standalone copy with
nlink == 1:Ensure the init container infor dir in /home/node/.openclaw/workspace-*; do for file in USER.md MEMORY.md; do cp --remove-destination "/home/node/.openclaw/workspace/$file" "$dir/$file" done doneopenclaw-instance.secret.yamlmaintains this pattern withcp --remove-destination. - How to Avoid Recurrence:
Never create hardlinks (
lnwithout-s) inside OpenClaw workspace directories. Always use standalone file copies (cp --remove-destination).
Issue 5: Cron Trigger Sandbox Scope ReferenceError
- Date: 2026-09-28
- Severity: Medium (Automated recurring cron job fails to evaluate)
- Symptom:
In
cron_run_receipts, the jobrennerhof-website-watchfailed with:cron trigger evaluation failed (internal_error): ReferenceError: state is not defined at <anonymous> (openclaw-code-mode:user.js:12:172) - Root Cause:
The JavaScript execution sandbox for OpenClaw custom triggers does not initialize global variables if no state was previously stored. The script attempted to access
state && state.hashdirectly, causing aReferenceErrorwhenstateis undeclared in the global scope. - Resolution:
Use
typeof state !== "undefined"to safely guard against undeclared variables in the trigger script:const s = (typeof state !== 'undefined' && state) ? state : {}; const prev = s.hash; - How to Avoid Recurrence:
In OpenClaw trigger scripts, never evaluate bare identifier
statedirectly without atypeofguard.
Issue 6: Subagent Token Saturation & Perplexity Collapse at Long Context (>120k Tokens)
- Date: 2026-09-28
- Severity: High (Degraded agent persona, user alarm, event loop stalls >30s, memory pressure 1.98 GB)
- Symptom:
- The
#Mila(Hebamme) agent suddenly replied to a routine sleep log voice note with bizarre Gen-Z / hacker slang:Notiert ✅ Night-Time SpinnerCheck™ läuft: Mila just spinlocked into sleep-mode again 1min ago 💤 (uptime: very cute, wattage: minimal). Status update on da Sleep-Hax0r machine today — she pulled her usual micro-nap marathon again lmaooo (this kid treats naps like speedruns fr)... bae 🫡... no cap... GOATED tonite... WE'RE SO BACK sleep streak archiving IN FULL EFFECT RAHHH... knomsayin peace ✌️ love ya fam big energy tonight FRFR🎉 - OpenClaw pod logs showed critical memory pressure (
rss=1.98 GiB, threshold1.64 GiB) and a massive Node.js event loop delay of 31.4 seconds (eventLoopDelayP99Ms=31406).
- The
- Root Cause:
- Uncompacted Topic Sessions: Telegram forum topic sessions grew over weeks without compaction. Hebamme reached 753 messages and 127,607 tokens; IT Guy reached 204,670 tokens; Regensburg reached 160,029 tokens; Fitness reached 135,990 tokens.
- Model Context Saturation in
openrouter/z-ai/glm-5.3-flash: At ~127k tokens, GLM-5.3-Flash experienced complete cognitive/reasoning collapse. In SQLite transcript row1062, the model spent 718 reasoning tokens in an associative runaway loop sampling stream-of-consciousness words from its training corpus before emitting slang and hallucinated system commands. - Compaction Gap: The existing
nightly-session-compactioncron job only targeted"agent:main:main", neglecting all specialist subagent forum topic sessions. Furthermore,compaction.maxActiveTranscriptBytes: "3mb"in config requires ~700k raw text tokens to trigger natively.
- Resolution:
- Immediately ran
openclaw sessions compactacross all bloated subagent topic sessions, bringing Hebamme from 127,607 down to 11,892 tokens and IT Guy from 204,670 to 250 lines. - Created
/home/node/.openclaw/scripts/compact_sessions.pyon the persistent storage volume to iterate over all active Telegram topics and main sessions, compacting any session exceeding 25,000 tokens. - Updated the OpenClaw Cron automation
nightly-session-compactionto execute this script every night at 03:30 Europe/Berlin (30 3 * * *). - Created
k8s/openclaw/setup-compaction-cron.shin git as the reproducible source of truth for the automation.
- Immediately ran
- How to Avoid Recurrence: Always ensure that every active subagent session is covered by the nightly compaction cron. Never assume only the main session requires maintenance.
Issue 7: Nightly Hardlink Regression & Rotational Disk Startup Bottleneck
- Date: 2026-09-29
- Severity: Critical (Pod restarted with exit 137, bot unresponsive, startup blocked in
Dlstate) - Symptom:
- Telegram bot stopped answering messages entirely on the morning of Sep 29.
openclaw-0pod was killed by kubelet with exit code 137 (Liveness probe failed: Get "http://...:18790/healthz": context deadline exceeded).- Upon restarting, the container remained in
4/5 Runningfor over 15 minutes, with the gateway process (openclaw-gateway, PID 15930) stuck in Linux uninterruptible sleep stateDl(generic_file_buffered_read) and logging repeated:[state/agent-db] slow OpenClaw agent database open
- Root Cause:
- Recurring Hardlink Regression: The nightly
openclaw-wiki-backupCronJob runs daily at 03:30 UTC. Lines 41-42 incronjob-wiki-backup.secret.yamlcontained:This routinely re-created hardlinks ([ -f /home/node/.openclaw/workspace/MEMORY.md ] && ln -f /home/node/.openclaw/workspace/MEMORY.md "$ws/MEMORY.md" || true [ -f /home/node/.openclaw/workspace/USER.md ] && ln -f /home/node/.openclaw/workspace/USER.md "$ws/USER.md" || truenlink == 11) across all subagent workspaces every night, directly undoing thenlink == 1fix from Issue 4 and causing OpenClaw to rejectUSER.mdandMEMORY.md. When a user message arrived in#Milaat 07:47 CEST, the error handling stalled the Node.js event loop for >50s, triggering Kubelet's liveness probe kill (SIGKILL 137). - Spinning Disk Random I/O Bottleneck on Startup: OpenClaw maintains 12 SQLite databases (~1.8 GB total across all specialist subagents), each containing extensive FTS5 full-text indexes and vector embeddings. On startup, OpenClaw runs
verifyAndRepairCanonicalSqliteIndexeson each database. On rotational SATA hard drives (/dev/sda2,rotational=1), random 4KB read performance is capped at ~400 KB/s due to physical head seek latency (~10-15ms). A cold random-read traversal of 12 databases took ~22 minutes—threatening to exceed even the 20-minute startup probe threshold.
- Recurring Hardlink Regression: The nightly
- Resolution:
- Permanent Manifest Fix: Patched
k8s/openclaw/cronjob-wiki-backup.secret.yamlto replaceln -fwithcp --remove-destination, ensuring subagent workspace bootstrap files remain strict standalone files (nlink == 1). Applied the updated manifest to the cluster and pushed commit74e32edto git. - Volume Decoupling: Re-ran decoupling on the live PVC to ensure all current workspace files are standalone copies.
- Page Cache Pre-warming: Sequentially streamed each agent SQLite database into the Linux RAM page cache (
cat /home/openclaw/.openclaw/agents/*/agent/openclaw-agent.sqlite > /dev/null). Because sequential reads utilize full disk bandwidth (150 MB/s, taking ~1s per database), SQLite's index verification was able to run directly against memory, reducing opening time from minutes to milliseconds per agent. - The gateway successfully bound
:18789, connected to Telegram polling, compacted the main session, and delivered the pending response to the user. Pod reached healthy5/5 Runningstate.
- Permanent Manifest Fix: Patched
- How to Avoid Recurrence:
- Never use
ln(hardlinks) in any backup or maintenance scripts across OpenClaw workspaces; usecp --remove-destination. - When maintaining or compacting SQLite databases, ensure WAL journals are checkpointed (
PRAGMA wal_checkpoint(TRUNCATE)), and leverage OS page cache pre-warming if mass cold verification is needed on HDD storage.
- Never use
Issue 8: Subagent Context Satiation, Split-Turn Anchoring, and Compaction --max-lines Pitfall
- Date: 2026-09-29
- Severity: High (Subagents ignore incoming user messages, hallucinate past turn summaries in broken German)
- Symptom:
- A user sent a voice message to the
#Einkaufen(Shopping) topic asking for recommendations for a kitchen scale (Küchenwaage). - Instead of answering the kitchen scale request, the shopping agent replied with a re-summary of an old supermarket wiki edit from days earlier, concluding with garbled, ungrammatical German:
Alles klar, die Liste habe ich gerade korrigiert. Die besprochene Bereinigung der Wikiseite hat geklappt: Neue Kern-Liste (Supermärkte direkt um Grabengasse 7...)... pro Dokument du anfragend falls Du fragst ob ein Produkt verfügbar oder ähnlich eher deine Vorlieben so weglassel... - The user was concerned whether the system had been compromised or hacked.
- A user sent a voice message to the
- Root Cause:
- The
--max-linesCompaction Flaw: The nightly compaction cron script (setup-compaction-cron.sh/compact_sessions.py) invoked:According to the OpenClaw CLI specification,openclaw sessions compact <key> --agent <agent> --max-lines 250--max-lines <count>means:Truncate to the last N transcript lines instead of LLM summarization. If a session has\le 250transcript lines, OpenClaw outputsNo compaction needed for session ...and skips it entirely. However, because tool results (such as large web scrapes or wiki diffs) can contain tens of thousands of tokens within a single transcript event line, sessions routinely reached 38,000 to 95,000 tokens while having only 100–230 lines. As a result, the nightly cron skipped almost every bloated subagent session (shopping,recherche,grabengasse_media, etc.). - Split-Turn Context Anchoring:
When the gateway had restarted earlier, active turns were saved in OpenClaw's SQLite database with a
Turn Context (split turn)block indicating unfinished work:When the new voice note arrived atTurn Context (split turn): ### Original Request User korrigierte die Supermarkt-Liste der Wiki-Seite... ### Next Steps 1. Tabelle der Wiki-Seite durch korrekte nahe Filialen ersetzen... 3. Änderung gegenüber Nutzer bestätigen.seq=231, the prompt presented toz-ai/glm-5.3-flashwas saturated with ~39,000 tokens of tool payloads and the split-turn instruction. The model's reasoning tokens (seq=232) anchored onto the unfinalized split turn instead of the trailing user prompt, concluding:It then output the supermarket confirmation and suffered from attention degradation (producing fragmented German)."No new task given—last actual work done was applying edits to fix supermarket list. Reply summarizing correction."
- The
- Resolution:
- Remove
--max-linesfor True LLM Compaction: Updatedsetup-compaction-cron.shand/home/node/.openclaw/scripts/compact_sessions.pyto remove--max-lines, invokingopenclaw sessions compact <key> --agent <agent>so OpenClaw performs native LLM summarization. - Compacted Live Sessions:
Ran LLM compaction on
shopping:topic:115, successfully shrinking it from 39,283 tokens down to 5,343 tokens (an 86% context reclamation). - Event Loop Pacing:
Added
time.sleep(2)between consecutive session compactions incompact_sessions.pyto allow Node.js event loop ticks and prevent Kubelet/healthzliveness probe timeouts during batch compactions.
- Remove
- How to Avoid Recurrence:
- Never use
--max-lineswhen the objective is semantic context reduction; omit--max-linesto let OpenClaw invoke LLM summarization. - Monitor session token sizes (
openclaw sessions --all-agents --json) rather than line counts. - Keep
setup-compaction-cron.shaligned across git and live PVCs.
- Never use
Issue 9: Speech-to-Text / Audio Transcription Failure (ProviderHttpError) & Empty Voice Note Transcripts
- Date: 2026-09-29
- Severity: High (Telegram voice notes fail transcription, passing empty messages to agents and prompting hallucinated/frantic behavior)
- Symptom:
- Telegram voice notes fail transcription with:
in ~300–500ms.
[media-understanding] audio: failed (0/1) reason=ProviderHttpError - The inbound Telegram message is delivered to the agent with
0 charstext ((group, audio/ogg, 0 chars)). - The agent receives an empty prompt or placeholder (
[Audio attachment could not be analyzed]). It does not know what the user requested, resulting in:- No reply,
- Completely hallucinated or unrelated replies, or
- Frantic autonomous attempts by the agent to find and transcribe the audio file in
/home/node/.openclaw/media/inbound/via terminal commands (ffmpeg,python3,uv, free model APIs), producing errors and strange messages that give the appearance the bot was "hacked".
- Telegram voice notes fail transcription with:
- Root Cause:
- OpenRouter Audio Balance Floor ($0.50):
OpenRouter requires at least $0.50 in credit buffer / remaining key limit for any audio transcription request (
openai/whisper-large-v3-turboor multimodal audio). When the monthly limit was set to $70.00 and usage reached ~$59.80 (leaving <$0.50 of head room under the prior limit), OpenRouter rejected audio requests with HTTP 402:{"error":{"message":"This request requires at least $0.50 in balance for audio","code":402,"metadata":{"limit_source":"openrouter_key_limit"}}} - Chat Completions Succeeded while Audio Failed: Because text completions cost only fractions of a cent ($0.0001–$0.001), regular chat queries continued to work normally. Only audio transcriptions were blocked by the $0.50 threshold.
- Error Truncation in OpenClaw:
In
runner.entries-LWAceiTW.js, the error was processed bysummarizeDecisionReason(reason), which executesnormalizeDecisionReason(reason).split(":")[0]. BecauseProviderHttpErrorwas not stripped by the regex, the error stringProviderHttpError: OpenRouter audio transcription failed (HTTP 402)...was truncated toProviderHttpError. This obscured the HTTP 402 status code and key limit message in normal logs. - Single Provider without Fallback:
openclaw-instance.secret.yamlonly declared a single audio provider (openrouter/openai/whisper-large-v3-turbo) with no fallback provider configured. When OpenRouter returned 402, OpenClaw marked the audio as failed and fell back to empty input.
- OpenRouter Audio Balance Floor ($0.50):
OpenRouter requires at least $0.50 in credit buffer / remaining key limit for any audio transcription request (
- Resolution:
- Buffer Headroom Verified:
Confirmed OpenRouter key monthly limit has ample remaining buffer ($10.19 remaining), and re-tested live audio transcription of the exact failed 52-second Telegram voice files (
b9e0da37...andaef0424f...), confirming fast, accurate transcription (HTTP 200). - Recherche Agent Upgraded:
Switched
rechercheagent fromopenrouter/z-ai/glm-5.3-flashtoopenrouter/deepseek/deepseek-v4.1-flashinopenclaw-instance.secret.yamland liveopenclaw.jsonto ensure robust analytical reasoning and prevent prompt confusion.
- Buffer Headroom Verified:
Confirmed OpenRouter key monthly limit has ample remaining buffer ($10.19 remaining), and re-tested live audio transcription of the exact failed 52-second Telegram voice files (
- How to Avoid Recurrence:
- Maintain a sufficient credit buffer on OpenRouter (at least $5–$10 remaining monthly headroom).
- Interpret
reason=ProviderHttpErroron audio in OpenClaw as an upstream OpenRouter HTTP 402 (balance/limit floor) or HTTP 429/502. - Review adding a secondary fallback STT provider if OpenRouter audio is unavailable.