Summary
~/.openclaw/agents/<name>/sessions/sessions.json keeps cliSessionId, previousSessionIds, and transcriptPath as null indefinitely on the main agent record. As a result, when the runtime spawns a fresh claude -p for the same agent (e.g. after a cron callback or compaction-induced restart), it can't --resume the prior CLI session — every CLI process exit becomes a context wipe.
Versions
- openclaw
2026.4.21
- claude CLI
2.1.114
- macOS Darwin 25.3.0
Repro
- Run main agent for an extended session via
claude -p. Confirm transcript accumulates under ~/.claude/projects/<workspace-path>/<sessionId>.jsonl.
- Trigger a fresh CLI process (cron callback with
wakeMode: now, or let the underlying CLI session rotate from a config change / plugin reload).
- Inspect
~/.openclaw/agents/<name>/sessions/sessions.json for the agent.
Observed:
```json
{
"sessionId": "41eda629-c62a-4e36-a98c-86653422682a",
"cliSessionId": null,
"previousSessionIds": null,
"transcriptPath": null,
"sessionFile": "/Users/.../agents/main/sessions/41eda629-...jsonl"
}
```
The runtime never populated the resume-chain fields, even though the actual CLI transcripts exist on disk under ~/.claude/projects/.
Expected
On each CLI process spawn, the runtime should:
- Capture the new
claude -p session ID into cliSessionId
- Append the prior
cliSessionId to previousSessionIds (or maintain a chain)
- Resolve and store the transcript path so resume can be reattempted
When spawning a fresh CLI for the same agent (e.g. cron callback), pass --resume <cliSessionId> so the new process inherits the prior session's history.
Real-world impact
Today's session went: long productive run ended at session 3b7fe27b... (982KB transcript, 18:22 EDT) → cron callback at 18:23 EDT spawned 6d0a999c... with no resume → user's next message in 336dcf95... at 18:26 EDT had zero context for the immediately-prior conversation. From the user's perspective: "are you sure the callbacks need to be that long?" → "what callbacks?"
Workaround in place
At the content layer, installed a Claude Code SessionStart hook in ~/.claude/settings.json that reads STATE.md and MEMORY.md from the workspace and emits them via hookSpecificOutput.additionalContext. Plus overrode agents.defaults.heartbeat.prompt in ~/.openclaw/openclaw.json because the default prompt (in dist/heartbeat-BARAswcJ.js) contains "Do not infer or repeat old tasks from prior chats" — which directly contradicted the hook-injected continuity context.
These workarounds restore summarized continuity. They can't substitute for actual --resume because STATE.md only captures the current state, not the conversation history (intermediate tool calls, sub-agent reasoning, etc.).
Suggested fix scope
- Where the runtime invokes
claude -p, capture the resulting session ID (visible via Claude Code SDK output / transcript filename) and persist it onto the agent record before any subsequent spawn.
- On subsequent spawns, prefer
--resume <previous> and only fall back to fresh-session when resume fails (e.g. transcript was rotated/cleaned up).
Happy to provide more transcripts or a minimal repro on request.
Summary
~/.openclaw/agents/<name>/sessions/sessions.jsonkeepscliSessionId,previousSessionIds, andtranscriptPathasnullindefinitely on the main agent record. As a result, when the runtime spawns a freshclaude -pfor the same agent (e.g. after a cron callback or compaction-induced restart), it can't--resumethe prior CLI session — every CLI process exit becomes a context wipe.Versions
2026.4.212.1.114Repro
claude -p. Confirm transcript accumulates under~/.claude/projects/<workspace-path>/<sessionId>.jsonl.wakeMode: now, or let the underlying CLI session rotate from a config change / plugin reload).~/.openclaw/agents/<name>/sessions/sessions.jsonfor the agent.Observed:
```json
{
"sessionId": "41eda629-c62a-4e36-a98c-86653422682a",
"cliSessionId": null,
"previousSessionIds": null,
"transcriptPath": null,
"sessionFile": "/Users/.../agents/main/sessions/41eda629-...jsonl"
}
```
The runtime never populated the resume-chain fields, even though the actual CLI transcripts exist on disk under
~/.claude/projects/.Expected
On each CLI process spawn, the runtime should:
claude -psession ID intocliSessionIdcliSessionIdtopreviousSessionIds(or maintain a chain)When spawning a fresh CLI for the same agent (e.g. cron callback), pass
--resume <cliSessionId>so the new process inherits the prior session's history.Real-world impact
Today's session went: long productive run ended at session
3b7fe27b...(982KB transcript, 18:22 EDT) → cron callback at 18:23 EDT spawned6d0a999c...with no resume → user's next message in336dcf95...at 18:26 EDT had zero context for the immediately-prior conversation. From the user's perspective: "are you sure the callbacks need to be that long?" → "what callbacks?"Workaround in place
At the content layer, installed a Claude Code
SessionStarthook in~/.claude/settings.jsonthat readsSTATE.mdandMEMORY.mdfrom the workspace and emits them viahookSpecificOutput.additionalContext. Plus overrodeagents.defaults.heartbeat.promptin~/.openclaw/openclaw.jsonbecause the default prompt (indist/heartbeat-BARAswcJ.js) contains "Do not infer or repeat old tasks from prior chats" — which directly contradicted the hook-injected continuity context.These workarounds restore summarized continuity. They can't substitute for actual
--resumebecause STATE.md only captures the current state, not the conversation history (intermediate tool calls, sub-agent reasoning, etc.).Suggested fix scope
claude -p, capture the resulting session ID (visible via Claude Code SDK output / transcript filename) and persist it onto the agent record before any subsequent spawn.--resume <previous>and only fall back to fresh-session when resume fails (e.g. transcript was rotated/cleaned up).Happy to provide more transcripts or a minimal repro on request.