/openclaw-ops - OpenClaw Configuration and Operations
Activate when configuring OpenClaw, parsing its status output, setting up Telegram integrations, or troubleshooting agent memory search. These are non-obvious config gotchas that cost time to rediscover.
Steps
1. Verify Config After openclaw doctor --fix
openclaw doctor --fix applies schema normalization which reverts manual customizations to defaults. After every doctor invocation, check these settings:
openclaw doctor --fix
# Always re-verify after:
jq '.agents.defaults.groupPolicy' ~/.openclaw/openclaw.json
# If reverted to "allowlist", restore:
jq '.agents.defaults.groupPolicy = "open"' ~/.openclaw/openclaw.json > tmp && mv tmp ~/.openclaw/openclaw.json
Reapply any custom values (groupPolicy, telegram bindings, plugin enables) after each doctor run.
2. memorySearch Config Nesting
Place memorySearch under agents.defaults, not at top level or at agents:
// Correct
{ "agents": { "defaults": { "memorySearch": { ... } } } }
// Wrong (top-level, silently ignored)
{ "memorySearch": { ... } }
// Wrong (wrong nesting level)
{ "agents": { "memorySearch": { ... } } }
3. Status JSON Agent Nesting
When parsing openclaw status --json, agents are at result.agents.agents (an array), not result.agents:
const status = JSON.parse(await execFileAsync('openclaw', ['status', '--json']))
const agentList = status.agents.agents // array
// NOT: status.agents (object with nested structure)
4. Telegram Long-Polling Watchdog
Telegram long-polling connections die after ~8 minutes idle. Add a cron watchdog to auto-restart the gateway:
# Add to crontab: crontab -e
*/5 * * * * ~/.claude/scripts/telegram-watchdog.sh >> ~/.openclaw/logs/watchdog.log 2>&1
The watchdog script should:
- Check the last activity timestamp from the gateway log
- If stalled more than 10 minutes, run
launchctl bootoutthenlaunchctl bootstrap(notstop/start) - Log the restart event with timestamp
5. Embedded Gateway Token Warning on macOS
Doctor flags Gateway service embeds OPENCLAW_GATEWAY_TOKEN and should be reinstalled. and recommends openclaw gateway install --force. On macOS this does not clear the warning (verified in 2026.4.23). The audit at dist/service-audit-*.js skips the warning only when environmentValueSources.OPENCLAW_GATEWAY_TOKEN === "file"; the systemd module sets that field, but the launchd module has no file-source support. There is no --token-file option (only --password-file for password auth).
Practical workaround: tighten the plist permissions so they match ~/.openclaw/.env.
chmod 600 ~/Library/LaunchAgents/ai.openclaw.gateway.plist
Token in ~/.openclaw/openclaw.json is a ${OPENCLAW_GATEWAY_TOKEN} placeholder; the actual value lives in ~/.openclaw/.env (mode 600). After chmod, exposure matches. Doctor will keep firing the warning because it audits plist content, not perms. Treat as a known macOS-only false positive until upstream adds launchd file-source support.
6. Session Store Maintenance
Two distinct kinds of session debt that doctor reports separately:
# Entries pointing to missing transcript files (.jsonl deleted out from under sessions.json)
openclaw sessions cleanup --enforce --fix-missing \
--store ~/.openclaw/agents/<agent>/sessions/sessions.json
# Orphan transcript files (.jsonl on disk not referenced by sessions.json) — archive manually
cd ~/.openclaw/agents/<agent>/sessions
TS=$(date -u +%Y-%m-%dT%H-%M-%S.000Z)
for f in <orphan-uuid>.jsonl; do mv "$f" "$f.deleted.$TS"; done
--fix-missing is needed in addition to --enforce; without it, cleanup only handles age/count retention. Renaming to *.deleted.<ts> matches the pattern doctor itself uses, keeps the data recoverable, and clears the orphan count.
7. OpenClaw Sessions Cache the System Prompt
Sessions are sticky: sessions.json caches systemSent: true once a session has sent its system prompt. Editing SOUL.md or AGENTS.md does not take effect until that session is cleared:
- Send
/restartto the agent via Telegram DM - Only then test the updated configuration
Without this, you'll see the old cached behavior and incorrectly conclude your edit didn't work.
8. Guard Memory File Reads in Agent Configuration
If AGENTS.md unconditionally reads a date-stamped memory file (e.g. memory/2026-05-09.md) that doesn't exist yet, the resulting ENOENT drives the model into tool-error-recovery: it treats the error as transcript corruption and emits a duplicate canned fallback greeting alongside the legitimate reply. Guard the read with an existence check (ls) first, or provide a fallback value, rather than reading unconditionally.
Vector 0.40 VRL Gotchas
These gotchas apply when authoring VRL transforms for Vector 0.40 pipelines (SIEM log-lake and similar):
Regex named-capture type: named captures return
string | null(notstring). Always cast:string!(.captures.name)before passing tocontains(),starts_with(), etc. The linter error isE110 unexpected type..timestampis non-nullable:.timestampon an event is always present;?? now()fallback is a no-op and the VRL parser rejects it. Access.timestampdirectly.to_int(null)returns 0, not error:to_int(null)silently returns0instead of raising. If you need to distinguish "field missing" from "field is 0", checkexists(.field)first.No first-class functions (closures): VRL has no lambda/closure support. Map and filter operations must be written as loops with explicit
push/mutation.HTTP request headers format: use the
[[sources.foo.headers]]TOML array-of-tables format, not inlineheaders = {}. Inline format silently drops headers.encoding.codecrejected in sinks:encoding.codecis not a valid key in most sink encoding blocks. Useencoding.only_fields,encoding.except_fields, andencoding.timestamp_formatonly.Disk buffer minimum size: Vector disk buffer requires at least 268,435,488 bytes (256 MiB + 32 bytes). Values below this crash Vector at startup with a confusing "invalid configuration" error. Set
max_size = 268435456(256 MiB) as the practical floor -- Vector rounds up the 32-byte header internally.syslog source emits 12 non-schema fields: the
syslogsource emitsappname,facility,hostname,message,msgid,procid,severity,source_ip,timestamp,version, plusstructured_dataandsource_type. If your downstream sink expects a clean schema, addencoding.only_fields = ["appname", "facility", "hostname", "message", "severity", "timestamp"](adjust to your schema) to avoid sending surprise fields to ClickHouse/Kafka.
Source Instincts
openclaw-doctor-revert: "when running openclaw doctor after manual config edits"openclaw-memorysearch: "when configuring memory search in OpenClaw"openclaw-agents-nesting: "when parsing openclaw status --json output"telegram-polling-watchdog: "when integrating Telegram with long-polling"openclaw-launchd-token-gap: "when doctor reports embedded OPENCLAW_GATEWAY_TOKEN on macOS"openclaw-session-cleanup: "when doctor reports orphan transcripts or missing-transcript entries"