openclaw - ✅(Solved) Fix heartbeat: isolatedSession: true silently reuses the same transcript file across every run [4 pull requests, 1 participants]
ON THIS PAGE
Recommended Tools
×6Utilities matched from this issue’s tags and category — try them while you read without losing context.
GitHub issue graph ai analysis
Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.
The report is written in English Markdown for sharing and archival.
Helpful · Quick feedback
agents.defaults.heartbeat.isolatedSession: true is documented as producing a fresh session (with a new sessionId and an empty transcript) on every heartbeat run, but in practice it only rolls the sessionId in the store entry — the persisted sessionFile path is preserved via a spread, so every run keeps appending to the same physical transcript file forever. Over time the file accumulates the full history of every prior heartbeat, and each new run sees all of it in its in-context window, which is the exact opposite of isolation.
This is provable from the code alone without any production evidence.
Root Cause
Because the entry always has a sessionFile after the first-ever run, the if (candidate) branch is taken and the function never falls through to computing a fresh path from sessionId.
Fix Action
Fix / Workaround
isolatedSession: truesilently does nothing after the first run. Every existing deployment that relies on it has been running without isolation.lightContext: true's documented token savings are optimistic by ~20x. The ~100K → ~2-5K figure only holds on the first run; every subsequent run incurs the full accumulated transcript.- Model behavior drifts toward the reinforced pattern. Any acknowledgment, summary, or tool-call sequence from an early run gets few-shot-learned by later runs and becomes sticky — even after config or prompt changes intended to alter the behavior.
- Context-overflow cliff. On a long-running deployment the file eventually exceeds the model's context window. Compaction on a transcript that is mostly tool-call noise fires
compaction-safeguard: no real conversation messages to summarizeand only writes a boundary marker, giving little real relief. - No user-visible workaround. There is no chat/CLI command that resets a non-current session, so affected users have to
rmthe file by hand from the pod's filesystem.
PR fix notes
PR #64797: fix(agents): clear sessionFile when rolling a fresh isolated session
- Repository: openclaw/openclaw
- Author: alexander-applyinnovations
- State: closed | merged: False
- Link: https://github.com/openclaw/openclaw/pull/64797
Description (problem / solution / changelog)
Summary
- Problem:
resolveCronSessionpreserves the existing entry'ssessionFilevia...entrywhenever a newsessionIdis generated (forceNew or stale).resolveSessionFilePathprefersentry.sessionFileoversessionIdwhen deciding where to write, so every new session keeps appending to the same physical transcript file forever. - Why it matters: For heartbeats configured with
isolatedSession: true(which is how the docs describe the "fresh session per run" behavior), the transcript file grew unbounded across every run, poisoning each new run with the in-context history of all prior runs — the exact opposite of isolation.lightContext: true's documented ~100K→~2–5K token savings silently regressed as the file grew. - What changed: One-line addition in
src/cron/isolated-agent/session.ts—sessionFile: undefinedin the existingisNewSessioncleanup block (next tolastChannel,lastTo,lastThreadId,deliveryContext). The resolver now falls through toresolveSessionTranscriptPathInDir(sessionId, …)and produces a new file named after the new sessionId. - What did NOT change: Only the
isNewSessioncleanup block is touched. Non-forceNewreuse of fresh sessions continues to preservesessionFileas before. Delivery routing clears, the...entryspread of overrides, and every other field stays intact.
Change Type (select all)
- Bug fix
Scope (select all touched areas)
- Gateway / orchestration
- Memory / storage
Linked Issue/PR
- Closes #64795
- Related #64196
- This PR fixes a bug or regression
Root Cause (if applicable)
- Root cause: The
isNewSessioncleanup block inresolveCronSessionclears delivery-routing fields but notsessionFile. Since the returned entry is built by spreading the old entry first, the stalesessionFileis always carried forward, and downstreamresolveSessionFilePath/resolveAndPersistSessionFileboth prefer a persistedsessionFileover recomputing fromsessionId. Net effect: the logical session rolls but the physical transcript file never rotates, defeatingisolatedSession: true. - Missing detection / guardrail: No regression test existed for rotating
sessionFilewhenforceNewor stale reset generates a newsessionId. Existing tests cover delivery-routing clears (lastChannel,deliveryContext) but not filesystem path isolation. - Contributing context:
sessionFilewas (correctly) added to theSessionEntrypersistence layer to keep the transcript path stable across reuse of fresh sessions. TheisNewSessionbranch inherited the same preservation semantics without carving out forceNew/stale rotation.
Regression Test Plan
- Coverage level: Unit test (pure, no filesystem)
- Target test file:
src/cron/isolated-agent/session.test.ts - Scenarios the test locks in:
clears sessionFile when forceNew is true— assertsresult.sessionEntry.sessionFileisundefinedafterforceNew: trueagainst an entry with a populatedsessionFile.clears sessionFile when session is stale— same assertion on the stale-freshness branch (noforceNew, butevaluateSessionFreshnessreturns{ fresh: false }).preserves sessionFile when reusing fresh session— asserts that a reused fresh session still carries itssessionFileunchanged, so this fix doesn't regress the normal reuse path.
- Why: these three cases cover every branch of
resolveCronSessionwhere the entry'ssessionFilematters, and they're the smallest pure-unit guardrails that would have caught the original bug.
User-visible / Behavior Changes
For agents with isolatedSession: true, each heartbeat run will now correctly write to a new transcript file named after the current run's sessionId. The old frozen transcript file will be orphaned on disk and cleaned up by the session reaper on its next pass (or can be removed manually).
Diagram
Before:
[heartbeat t1] -> resolveCronSession(forceNew:true)
-> sessionId = uuid-A
-> entry = {...oldEntry, sessionFile: oldPath, sessionId: uuid-A}
-> transcript writer appends to oldPath
[heartbeat t2] -> resolveCronSession(forceNew:true)
-> sessionId = uuid-B (new!)
-> entry = {...t1Entry, sessionFile: oldPath, sessionId: uuid-B}
-> transcript writer appends to oldPath (same file!)
...many runs...
-> file contains all historical messages
-> model sees all prior HEARTBEAT replies as in-context history
-> few-shot-learns the pattern, reinforces it forever
After:
[heartbeat t1] -> resolveCronSession(forceNew:true)
-> sessionId = uuid-A
-> entry = {...oldEntry, sessionFile: undefined, sessionId: uuid-A}
-> resolver falls through to resolveSessionTranscriptPathInDir
-> transcript writer creates/appends uuid-A.jsonl
[heartbeat t2] -> resolveCronSession(forceNew:true)
-> sessionId = uuid-B
-> entry = {...t1Entry, sessionFile: undefined, sessionId: uuid-B}
-> resolver falls through again
-> transcript writer creates/appends uuid-B.jsonl (fresh file!)Security Impact (required)
- New permissions/capabilities?
No - Secrets/tokens handling changed?
No - New/changed network calls?
No - Command/tool execution surface changed?
No - Data access scope changed?
No
No risk.
Repro + Verification
Environment
- OS: Linux (
registry.xlab.now/clankertron:2026.4.10on Kubernetes, Talos 1.11.2) - Runtime/container: Node.js via the openclaw container image (upstream base
ghcr.io/openclaw/openclaw) - Model/provider:
llamacpp-deep/qwen3.5-35b-a3b(backed byllama.cppHTTP server,ctx_size=65536) - Integration/channel: Telegram heartbeat target, 15-minute interval
- Relevant config:
agents: { defaults: { heartbeat: { every: "15m", isolatedSession: true, lightContext: true, // or false — both reproduce session: "main", // default target: "telegram", } } }
Steps (without this fix)
- Run a heartbeat agent with
isolatedSession: truefor any length of time (multiple heartbeats). cat /data/agents/main/sessions/sessions.jsonand inspect theagent:main:main:heartbeatentry.- Note that
sessionIdrolls on every run butsessionFileis stable. - Inspect the transcript file at the path in
sessionFile. - Observe that
grep -c '"type":"session"' <file>returns1— only one session record even though many runs have occurred. - Observe that the file grows monotonically and accumulates the history of every heartbeat run.
Expected
Each forceNew heartbeat should produce a new transcript file (or at least a new session record in a rotated file), with no in-context history from prior runs.
Actual (before fix)
The same transcript file is reused across every run. The model sees ~100K tokens of accumulated prior-run history on every heartbeat. "Fresh session per run" is not achieved for any run past the first.
Actual (with this fix)
After the first heartbeat post-fix, the store entry's sessionFile is cleared on each forceNew run. resolveSessionFilePath falls through and allocates a new <sessionId>.jsonl file. Each run's transcript is isolated.
Evidence
Forensic data from a live deployment
sessions.json for agent:main:main:heartbeat on a live cluster (five hours after the pod restarted):
{
"sessionId": "8f939e30-e4a3-479f-9eeb-2b21d4aaf57b",
"sessionFile": "/data/agents/main/sessions/34db8152-a3ac-4e7a-8c4a-9a38d9525339.jsonl",
"updatedAt": 1775908689677,
"heartbeatIsolatedBaseSessionKey": "agent:main:main"
}File on disk:
| metric | value |
|---|---|
| filename stem | 34db8152-a3ac-4e7a-8c4a-9a38d9525339 |
| transcript header session id | cbc883fc-6486-40d2-b0d1-6a102861f5df (first run ever, 2026-04-10T22:09:51Z) |
| distinct session records in file | 1 |
| lines | 433 |
| HEARTBEAT_OK ack tokens | 101 |
| oldest message | 2026-04-10T22:09:51Z |
| newest message | 2026-04-11T11:58:09Z |
Three distinct UUIDs observable for a single logical session:
34db8152…— filename (set once, never rotated)cbc883fc…— transcript-file session id (from the very first run)8f939e30…— currentsessionIdin the store (latestforceNew)
Log correlation (different sessionIds, same sessionFile)
From context-overflow diagnostics in the same deployment:
07:28 sessionId=da41fec7-997f-4a56-b5b5-a56cb3a11c28 sessionFile=…/34db8152-…jsonl
10:43 sessionId=f198e48b-84e6-4695-aabc-c4fed74d7cd1 sessionFile=…/34db8152-…jsonl
10:59 sessionKey=agent:main:main:heartbeat sessionFile=…/34db8152-…jsonl messages=974+ distinct sessionId values observed across 5 hours on the same sessionKey and the same sessionFile. The other 13 non-heartbeat session entries in the same store all have their filename stem matching their sessionId — only the heartbeat entry shows the mismatch, confirming the bug is scoped to the forceNew branch.
Provable from code alone
The bug is also provable purely by code walk:
resolveSessionFilePath(sessionId, entry)atsrc/config/sessions/paths.ts:263prefersentry.sessionFileover the sessionId-derived path.resolveAndPersistSessionFileatsrc/config/sessions/session-file.ts:17-27only consultsfallbackSessionFilewhen!baseEntry.sessionFile.- The return entry from
resolveCronSessionis built by spreading...entry(which carriessessionFile) and theisNewSessioncleanup block does not includesessionFile. - Therefore, after the first run of any session that ever goes through
resolveCronSession, the stalesessionFileis returned on every subsequentforceNew/stale rotation.
Human Verification (required)
- Verified scenarios:
- Read every caller of
resolveSessionFilePathandresolveAndPersistSessionFileinsrc/to confirm no downstream path re-derives the file from the newsessionIdafterresolveCronSessionreturns. - Read the heartbeat-runner flow from
resolveCronSessionthroughsaveSessionStoreand the downstream transcript writer to confirm no intermediate reset exists. - Dumped
sessions.jsonfrom a live cluster and checked all 14 entries — 13 non-heartbeat sessions have correctly matching sessionId↔filename, only the heartbeat entry has the mismatch, confirming the bug is scoped toforceNewonly. - Verified the file header's session id (
cbc883fc) differs from the store's currentsessionId(8f939e30) and the filename stem (34db8152) — three distinct UUIDs for one logical session, exactly as the code predicts. - Verified that the same
sessionFileappears in log lines with four differentsessionIdvalues over 5 hours. - Verified that
sessionFile?: stringinSessionEntrytype allows theundefinedassignment; TypeScript is satisfied.
- Read every caller of
- Edge cases checked:
- First-ever run (no existing entry) — entry is
undefined, spread is a no-op,sessionFileisundefinedby default, resolver computes fromsessionId. Unchanged by this fix. - Reused fresh session (
!forceNew && fresh) — theisNewSessioncleanup block is skipped,sessionFileis preserved via the spread. Unchanged and covered by the newpreserves sessionFile when reusing fresh sessiontest. - Stale rotation (
!forceNew && !fresh) — now also clearssessionFile(was broken before). New test covers this. - Non-heartbeat
forceNewcallers (webhook cron runs via the sameresolveCronSession) — they get the same fix, which is also the documented behavior forsessionTarget: "isolated".
- First-ever run (no existing entry) — entry is
- What I did NOT verify:
- Actual vitest run of the new tests. This machine has no
node/pnpmavailable, so the tests were written by hand against the existingsession.test.tsconventions (sameresolveWithStoredEntryhelper, same mock shape). I am relying on CI to confirm the suite passes. Targeted test file:src/cron/isolated-agent/session.test.ts. - End-to-end live reproduction of the fix against our cluster — that requires a rebuild of the downstream
clankertronimage, which I have not done as part of this PR.
- Actual vitest run of the new tests. This machine has no
Compatibility / Migration
- Backward compatible?
Yes— the fix only changes behavior whenisNewSessionis true, which is exactly when the current behavior is wrong. No existing working path is altered. - Config/env changes?
No - Migration needed?
Nofor configuration, but operators of affected deployments will have a stale transcript file on disk that is no longer referenced. The session reaper should clean these up on its next pass. Manual cleanup is also safe (rmthe orphaned file once the sessions store no longer references it).
Risks and Mitigations
- Risk: Orphaned transcript files for existing deployments where the stale
sessionFilepath gets dropped from the store entry on the first post-fix run.- Mitigation: The files are only orphaned on disk; the session reaper (disk-budget maintenance) will reclaim them on its next pass. No user-visible regression. Operators can also manually delete the old transcript file — it has no operational value after the fix lands.
- Risk: Any code path that still reads a session entry's
sessionFileand expects it to be non-empty may seeundefinedon the first post-fix turn before the downstreamresolveAndPersistSessionFileruns.- Mitigation:
SessionEntry.sessionFileis already declared optional (sessionFile?: string) insrc/config/sessions/types.ts. All call sites I inspected use optional chaining or explicit null-checks. No TypeScript errors surfaced from the change.
- Mitigation:
AI-assisted
- Drafted with Claude Code (Claude Opus 4.6, 1M context)
- Lightly tested — the tests were written but NOT run locally due to a missing Node toolchain on the authoring machine. Relying on CI for the targeted test run.
- I understand what the code does — one-line addition to an existing conditional-clear block, plus three targeted regression tests.
🤖 Generated with Claude Code
Changed files
src/cron/isolated-agent/session.test.ts(modified, +58/-0)src/cron/isolated-agent/session.ts(modified, +7/-0)
PR #64808: fix(agents): archive rotated heartbeat transcript on isolatedSession rotation
- Repository: openclaw/openclaw
- Author: alexander-applyinnovations
- State: closed | merged: False
- Link: https://github.com/openclaw/openclaw/pull/64808
Description (problem / solution / changelog)
Summary
- Problem: Even with the
sessionFileclear from #64797, when anisolatedSession: trueheartbeat rotates to a new session the PRIOR transcript file at the old path becomes orphaned — referenced by nothing in the session store. The only mechanism that reaps it today isenforceSessionDiskBudgetinconfig/sessions/disk-budget.ts, which runs only when the budget is exceeded. On a deployment with a 15-minute heartbeat interval, orphaned transcripts accumulate to hundreds of MB before any cleanup happens. - Why it matters: Without immediate archival, operators see unbounded disk growth in the agent sessions directory even though each logical session is now correctly isolated. The file count and disk footprint still grow monotonically per heartbeat tick.
- What changed: In
src/infra/heartbeat-runner.ts, capture the prior entry's(sessionId, sessionFile)pair at the isolated-session key before the store update, feed it into a newresetSessionFilesmap, and archive viaarchiveRemovedSessionTranscriptswithreason: "reset"(rename to<file>.reset.<ts>, cleaned up later bycleanupArchivedSessionTranscriptsafter its retention window). Existing suffix-collapse case is split into adeletedSessionFilesmap so it continues to usereason: "deleted"— the two cases have different semantics and should get different retention classes. - What did NOT change (scope boundary): No changes to
resolveCronSessionorsession.ts(that's #64797). No changes toarchiveRemovedSessionTranscripts,archiveSessionTranscripts, orcleanupArchivedSessionTranscripts— reusing the existing battle-tested archival path. No new retention knobs — uses the existingmaintenance.resetArchiveRetentionMsfor rotation archives. TherunSessionKey = isolatedSessionKey;assignment and everything downstream of the saveSessionStore call is untouched.
Change Type (select all)
- Bug fix
Scope (select all touched areas)
- Gateway / orchestration
- Memory / storage
Linked Issue/PR
- Closes #64795 (partially — the sessionFile-clear fix is #64797; this PR addresses the orphan-accumulation follow-on)
- Related #64797 — this PR depends on #64797 landing first. Without the
sessionFileclear, the heartbeat runner seespriorEntry.sessionFilestill matching the inherited path afterresolveCronSessionreturns, and archiving it would leave the store entry pointing at a renamed file. The dependency is purely ordering: this PR's logic is correct once #64797 is in. - This PR fixes a bug or regression
Root Cause (if applicable)
- Root cause:
resolveCronSessionrotates to a newsessionIdon everyforceNew: trueheartbeat run, and once #64797 lands it also rotates to a newsessionFile. The prior transcript file at the old path is then referenced by no store entry — the runtime has no code path that proactively archives it. The only cleanup today is disk-budget enforcement, which is a last-resort mechanism, not an incremental one. - Missing detection / guardrail: There's no test that verifies "on rotation, the prior transcript is cleaned up". Existing heartbeat tests verify session-key stability and delivery routing but not file lifecycle.
- Contributing context: The existing
archiveRemovedSessionTranscriptscall inheartbeat-runner.ts:841already handled the stale:heartbeat:heartbeatsuffix-collapse case withreason: "deleted". Extending it to also archive rotation files is a natural extension of that pattern — the archival primitive is the same, only the input set and the semantics (reset vs deleted) differ.
Regression Test Plan
- Coverage level: Unit test (sandbox-based, exercises the full heartbeat runner with a temp session store)
- Target test file:
src/infra/heartbeat-runner.isolated-key-stability.test.ts - New test:
archives the prior transcript file as .reset when rotating to a fresh isolated session - Scenario the test locks in:
- Seed a session store with an
isolatedSessionKeyentry whosesessionFilepoints at an existing transcript on disk - Run
runHeartbeatOnce - Assert the prior transcript file has been renamed to
<id>.jsonl.reset.<ts>(no longer at the original path) - Assert the store entry still exists at the same key but with a different
sessionId - Assert the new
sessionFile(if defined) is different from the old one
- Seed a session store with an
- Why: this is the smallest reliable end-to-end test that locks in the archive-on-rotation contract and catches regressions if any path in
heartbeat-runner.tsbypasses the rotation archival.
User-visible / Behavior Changes
On deployments with isolatedSession: true, rotated transcript files now get immediately archived as <file>.reset.<ts> instead of sitting on disk indefinitely. The archival is reversible within the configured retention window (maintenance.resetArchiveRetentionMs). Operators who debugged prior heartbeat runs by reading the stable transcript file will instead find the archived rotations with timestamped suffixes, in chronological order.
Diagram
Before #64797:
[heartbeat t1] → transcript appended to sessions/foo.jsonl
[heartbeat t2] → same file, sessionId rolls in store but file keeps growing
[...many runs...] → one file, 100+ HEARTBEAT_OK replies poisoning each new run
After #64797 only:
[heartbeat t1] → sessions/sid-A.jsonl (fresh)
[heartbeat t2] → sessions/sid-B.jsonl (fresh, A is orphaned)
[heartbeat t3] → sessions/sid-C.jsonl (fresh, A+B orphaned)
[...many runs...] → N orphaned files, cleaned up eventually by disk-budget sweeper
After this PR (stacked on #64797):
[heartbeat t1] → sessions/sid-A.jsonl
[heartbeat t2] → sessions/sid-B.jsonl + sid-A.jsonl.reset.<t2-ts>
[heartbeat t3] → sessions/sid-C.jsonl + sid-B.jsonl.reset.<t3-ts>
(sid-A archive eventually cleaned by cleanupArchivedSessionTranscripts
after resetArchiveRetentionMs)Security Impact (required)
- New permissions/capabilities?
No - Secrets/tokens handling changed?
No - New/changed network calls?
No - Command/tool execution surface changed?
No - Data access scope changed?
No
No risk. The archival path is the same one already used by the suffix-collapse case and by the cron reaper — the change here is only when it runs and what input it's given. restrictToStoreDir: true is preserved.
Repro + Verification
Environment
- OS: Linux
- Runtime/container: Node.js via the openclaw container image
- Model/provider: any
- Integration/channel: any heartbeat target
- Relevant config:
agents: { defaults: { heartbeat: { every: "15m", isolatedSession: true, } } }
Steps (after #64797 lands, without this PR)
- Run a heartbeat agent with
isolatedSession: truefor any number of heartbeats (>2). ls /data/agents/main/sessions/*.jsonl— observe a growing number of orphaned transcript files, one per prior heartbeat run, none referenced by thesessions.jsonstore.- Wait for
enforceSessionDiskBudgetto run only when the budget is exceeded — typically hours to days to weeks depending onmaxDiskBytes.
Expected
Each rotation should immediately archive the prior transcript so disk usage stays bounded by the retention window, not by the disk budget.
Actual (without this PR)
Orphaned files accumulate. On a 15-min interval deployment, ~100 orphaned files per day, each 100-1000 bytes to kilobytes.
Actual (with this PR)
Each rotation immediately renames the prior file to <file>.reset.<ts>. After maintenance.resetArchiveRetentionMs elapses, the archive is cleaned up by cleanupArchivedSessionTranscripts on the next maintenance sweep.
Evidence
- New test
archives the prior transcript file as .reset when rotating to a fresh isolated sessionasserts the end-to-end behavior: prior transcript gone from its original path, archived file present at<id>.jsonl.reset.<ts>, store entry rotated to a new sessionId. - Existing test coverage (
heartbeat-runner.isolated-key-stability.test.ts) verifies the suffix-collapse case still works with its owndeletedSessionFilesmap andreason: "deleted".
Human Verification (required)
- Verified scenarios:
- Traced
cronSession.store[isolatedSessionKey]before thestore[isolatedSessionKey] = cronSession.sessionEntryassignment. At that point, the old entry with old sessionId and old sessionFile is still there, sopriorEntryAtKeycaptures exactly the values we want to archive. - Verified that
referencedSessionIds(computed fromObject.values(cronSession.store)AFTER the new entry is assigned) contains the NEW sessionId but not the OLD one, soarchiveRemovedSessionTranscriptswill not skip the archival for the old file. - Confirmed that the existing suffix-collapse case continues to use
reason: "deleted"and is gated onstaleIsolatedSessionKeybeing set, completely independent of the new rotation logic. - Read
archiveSessionTranscriptsDetailedto confirmrestrictToStoreDir: trueconstrains archival to the agent sessions dir viapath.relativecontainment check — no risk of touching unrelated files.
- Traced
- Edge cases checked:
- First-ever heartbeat run (no prior entry):
priorEntryAtKeyisundefined, no addition toresetSessionFiles, nothing to archive. Works. - Prior entry exists but has no
sessionFileset: conditionalpriorEntryAtKey.sessionFilecheck skips the add. Nothing archived. Works. - Both
staleIsolatedSessionKeyANDisNewSessiontrigger on the same run: both maps get populated, both archival calls run, each uses its own reason. The two maps are disjoint by construction (different sessionIds). - Reused fresh session (
isNewSession === false): the new conditional is skipped, no rotation archival happens,sessionFilecontinues to be used by the same entry. Works (the reuse path doesn't rotate the transcript).
- First-ever heartbeat run (no prior entry):
- What I did NOT verify:
- Actual
pnpm vitest runof the new test. This machine has no Node toolchain available, so I wrote the test by hand against the existingwithTempHeartbeatSandboxconvention and trust the harness. Targeted test file:src/infra/heartbeat-runner.isolated-key-stability.test.ts. - End-to-end verification on a live cluster. The cluster behavior can be observed after both PRs land and the image is rebuilt.
- Actual
Compatibility / Migration
- Backward compatible?
Yes— the new behavior only kicks in whenisNewSession === true, which already existed but had no archival. No existing working path is altered. - Config/env changes?
No— reuses existingmaintenance.resetArchiveRetentionMs/maintenance.pruneAfterMsknobs. - Migration needed? For existing deployments, orphaned transcript files from before both PRs land will still sit on disk until the first maintenance sweep after the upgrade. They're safe to
rmmanually if disk pressure is urgent. Everything from the first post-upgrade heartbeat onwards rotates cleanly.
Risks and Mitigations
- Risk: If #64797 does not land before this PR,
priorEntryAtKey.sessionFileis still inherited by the new entry via...entryspread, andarchiveRemovedSessionTranscriptswould rename a file that the new entry is about to write to. On the next write, the store entry'ssessionFilewould point at a file that no longer exists at that path.- Mitigation: This PR is explicitly documented as depending on #64797. Do not merge this PR before #64797. The branch is stacked on top of the #64797 branch for exactly this reason.
- Risk:
reason: "reset"usesmaintenance.resetArchiveRetentionMsfor cleanup, which may be shorter thanpruneAfterMs. Operators who relied on longer retention for debugging may find archives gone sooner.- Mitigation:
"reset"is semantically correct for rotation (the entry persists, only the transcript rolls). Operators who want longer retention can tunemaintenance.resetArchiveRetentionMsdirectly — it's an existing knob with existing docs.
- Mitigation:
AI-assisted
- Drafted with Claude Code (Claude Opus 4.6, 1M context)
- Lightly tested — the test was written but NOT run locally due to a missing Node toolchain on the authoring machine. Relying on CI for the targeted test run.
- I understand what the code does — ~15 lines of additions to heartbeat-runner.ts plus a ~55-line end-to-end test. The archival primitive is unchanged; only the input set and the reason classification are new.
🤖 Generated with Claude Code
Changed files
src/cron/isolated-agent/session.test.ts(modified, +58/-0)src/cron/isolated-agent/session.ts(modified, +7/-0)src/infra/heartbeat-runner.isolated-key-stability.test.ts(modified, +73/-0)src/infra/heartbeat-runner.ts(modified, +52/-12)
PR #64832: fix(agents): archive orphaned isolated-session transcripts after rotation
- Repository: openclaw/openclaw
- Author: alexander-applyinnovations
- State: open | merged: False
- Link: https://github.com/openclaw/openclaw/pull/64832
Description (problem / solution / changelog)
Summary
Complement to #65203. That PR cleared sessionFile on rotation so each isolatedSession: true run writes to a fresh path — but the prior transcript file at the old path is now orphaned: nothing in the store references it, and cleanupArchivedSessionTranscripts only scans for the .reset.<ts> suffix. Orphans accumulate forever.
This PR renames each prior transcript to <file>.reset.<ts> as part of the same rotation transaction, so it re-enters the retention window.
Change
Two helpers in src/cron/isolated-agent/session.ts:
capturePriorIsolatedEntryForArchival— snapshot prior(sessionId, sessionFile)before persist.archivePriorIsolatedEntryAfterRotation— rename to<file>.reset.<ts>after persist, withreason: "reset"(honorsmaintenance.resetArchiveRetentionMs). Uses the existingarchiveRemovedSessionTranscriptsprimitive.
Wired into both forceNew: true call sites:
src/infra/heartbeat-runner.ts— heartbeat rotation path. Also splits the existing:heartbeat:heartbeatsuffix-collapse archival into its own call withreason: "deleted"so the two archival paths get their correct retention classes (pruneAfterMsvsresetArchiveRetentionMs).src/cron/isolated-agent/run-session-state.ts— croncreatePersistCronSessionEntryclosure with a once-flag (persist is called multiple times per run: pre-run, skills refresh, finalize). Covers thecron:prefix case (runSessionKey = ...:run:<id>), where the session-reaper only archives the run-key entry on retention — not the prior agentSessionKey transcript. Without this path the cron orphan is never archived.
Tests lock in: capture timing (BEFORE persist), once-flag, cron-run-key path, archival failure handling, and a heartbeat-runner sandbox test that seeds a real prior transcript and asserts the rename.
Forensic evidence
xlab.now deployment running clankertron:2026.4.10 (pre-#65203) with a manual sessionFile clear as workaround: five heartbeat runs over seven hours each wrote to a fresh transcript, but five orphaned transcripts accumulated on disk (300 KB – 1.3 MB each). cleanupArchivedSessionTranscripts cannot see them — they don't carry the .reset.* suffix. At ~4 runs/hour × ~400 KB this is roughly 38 MB/day of unsweepable growth per deployment. This PR closes that gap at the rotation boundary.
Scope boundary
- No changes to
archiveRemovedSessionTranscripts,cleanupArchivedSessionTranscripts, or any archival primitive — reuses existing machinery from a new call site. - No new retention knobs.
- No changes to the pure-reuse (
!isNewSession) path. restrictToStoreDir: truepreserved throughout.
Safety
- Archival is wrapped in
try/catchat each call site; failure logs a warning but does not fail the run. - The
referencedSessionIdssafety guard insidearchiveRemovedSessionTranscriptsprevents archiving any sessionId still pointed at by another store entry. Callers compute this set from the post-update store.
Prior state of this PR
Originally scoped as the root-cause fix for sessionFile persistence. #65203 landed that root-cause fix independently on 2026-04-12 (the sessionFile: undefined line in resolveCronSession). This PR has been rebased on top of #65203 and narrowed to the archival flow only — the diff no longer contains the sessionFile: undefined change, only the orphan-cleanup machinery that neither #65203 nor any current code path provides.
🤖 Generated with Claude Code
Changed files
src/cron/isolated-agent/run-session-state.test.ts(added, +345/-0)src/cron/isolated-agent/run-session-state.ts(modified, +42/-1)src/cron/isolated-agent/run.test-harness.ts(modified, +5/-0)src/cron/isolated-agent/run.ts(modified, +6/-0)src/cron/isolated-agent/session.test.ts(modified, +225/-1)src/cron/isolated-agent/session.ts(modified, +65/-0)src/infra/heartbeat-runner.isolated-key-stability.test.ts(modified, +115/-0)src/infra/heartbeat-runner.ts(modified, +42/-7)
PR #64873: fix(cron): clear sessionFile on forceNew so isolated runs don't share transcripts
- Repository: openclaw/openclaw
- Author: mjamiv
- State: closed | merged: False
- Link: https://github.com/openclaw/openclaw/pull/64873
Description (problem / solution / changelog)
Summary
- Add
sessionFile: undefinedto theisNewSessioncleanup block inresolveCronSessionso that forced-new isolated runs don't inherit and keep writing to the previous transcript file. - Add three targeted tests in
src/cron/isolated-agent/session.test.tscovering forceNew, stale-session, and fresh-reuse paths.
Fixes #64795.
Root cause
resolveCronSession in src/cron/isolated-agent/session.ts rolls a new sessionId when forceNew: true (or when the stored session is stale), but it builds the returned entry by spreading the previous entry first:
const sessionEntry: SessionEntry = {
...entry, // ← spreads sessionFile from prior entry
sessionId, // ← overridden with the new uuid
updatedAt: params.nowMs,
systemSent,
...(isNewSession && {
lastChannel: undefined,
lastTo: undefined,
lastAccountId: undefined,
lastThreadId: undefined,
deliveryContext: undefined,
// sessionFile was NOT here — it survives into the new entry
}),
};Downstream, resolveSessionFilePath in src/config/sessions/paths.ts:263 prefers a persisted entry.sessionFile over recomputing a fresh path from sessionId:
export function resolveSessionFilePath(
sessionId: string,
entry?: { sessionFile?: string },
opts?: SessionFilePathOptions,
): string {
const sessionsDir = resolveSessionsDir(opts);
const candidate = entry?.sessionFile?.trim();
if (candidate) {
try {
return resolvePathWithinSessionsDir(sessionsDir, candidate, { agentId: opts?.agentId });
} catch { /* … */ }
}
return resolveSessionTranscriptPathInDir(sessionId, sessionsDir);
}So the returned entry ends up with a new sessionId but the old sessionFile. Every forced-new run appends to the same physical transcript file as the previous run, indefinitely.
Impact
This defeats two documented features:
-
agents.defaults.heartbeat.isolatedSession: true—docs/gateway/heartbeat.mdpromises "each heartbeat runs in a fresh session with no prior conversation history" and quotes~100K tokens down to ~2-5K per run. Neither holds while the stalesessionFilesurvives — every heartbeat turn reads the full accumulated transcript on context load. -
Cron
sessionTarget: "isolated"— isolated cron runs take the sameforceNew: truepath viaresolveCronSession, so the same transcript pollution affects cron jobs configured for full isolation.
The silent failure mode is particularly painful because it looks like heartbeat isolatedSession is working (new sessionId, new store entry, no forceNew warnings) while the underlying transcript file continues to accumulate every prior run's history.
Fix
One field added to the existing isNewSession cleanup block, with a comment explaining the downstream interaction with resolveSessionFilePath:
...(isNewSession && {
lastChannel: undefined,
lastTo: undefined,
lastAccountId: undefined,
lastThreadId: undefined,
deliveryContext: undefined,
+ sessionFile: undefined,
}),With sessionFile cleared on the isNewSession branch, resolveSessionFilePath falls through candidate = entry?.sessionFile?.trim() (which is now undefined) and computes the path from the new sessionId via resolveSessionTranscriptPathInDir. This is the exact intent of the existing cleanup block: strip anything that leaked from the prior session into a fresh one.
Test coverage
Added to the existing describe("session reuse for webhooks/cron") block in src/cron/isolated-agent/session.test.ts:
clears sessionFile when forceNew is true— covers the heartbeat isolatedSession and isolated cron paths.clears sessionFile when session is stale— covers the freshness-expiry path for direct-style cron/webhook sessions.preserves sessionFile when reusing a fresh session— locks in the negative: reuse must keep the transcript, because the whole point of reuse is that the transcript keeps accumulating.
Verification
- ✅
npx vitest run src/cron/isolated-agent/session.test.ts— 13/13 pass (the 3 new ones included). - ✅
npx vitest run src/cron/isolated-agent/session.test.ts src/config/sessions/sessions.test.ts src/config/sessions/store.lock.test.ts src/config/sessions/transcript.test.ts— 41/41 pass across the four related test files, no regressions in transcript/store code.
What this does NOT change
- No changes to
heartbeat-runner.tsor itsforceNew: truecall — the fix is purely in the session-roll helper so every caller benefits (isolated cron, heartbeat, webhook). - No changes to
resolveSessionFilePath— it still honors a persistedsessionFilewhen present, which is the correct behavior for non-isolated session reuse. - No config schema or docs changes — the documented behavior is now actually what the code does.
🤖 Generated with Claude Code
Changed files
src/cron/isolated-agent/session.test.ts(modified, +51/-0)src/cron/isolated-agent/session.ts(modified, +5/-0)
Code Example
if (useIsolatedSession) {
…
const cronSession = resolveCronSession({
cfg,
sessionKey: isolatedSessionKey,
agentId,
nowMs: startedAt,
forceNew: true,
});
---
if (!params.forceNew && entry?.sessionId) {
// reuse-or-roll logic
} else {
// No existing session or forced new
sessionId = crypto.randomUUID(); // ✓ new id
isNewSession = true;
systemSent = false;
}
…
const sessionEntry: SessionEntry = {
// Preserve existing per-session overrides even when rolling to a new sessionId.
...entry, // ← this carries sessionFile forward
sessionId, // ← overridden
updatedAt: params.nowMs,
systemSent,
// When starting a fresh session (forceNew / isolated), clear delivery routing…
...(isNewSession && {
lastChannel: undefined,
lastTo: undefined,
lastAccountId: undefined,
lastThreadId: undefined,
deliveryContext: undefined,
// sessionFile is intentionally NOT in this clear list
}),
};
---
export function resolveSessionFilePath(
sessionId: string,
entry?: { sessionFile?: string },
opts?: SessionFilePathOptions,
): string {
const sessionsDir = resolveSessionsDir(opts);
const candidate = entry?.sessionFile?.trim();
if (candidate) {
try {
return resolvePathWithinSessionsDir(sessionsDir, candidate, { agentId: opts?.agentId });
} catch {
// Keep handlers alive when persisted metadata is stale/corrupt.
}
}
return resolveSessionTranscriptPathInDir(sessionId, sessionsDir);
}
---
const baseEntry = params.sessionEntry ?? sessionStore[sessionKey] ?? { sessionId, updatedAt: Date.now() };
const fallbackSessionFile = params.fallbackSessionFile?.trim();
const entryForResolve =
!baseEntry.sessionFile && fallbackSessionFile
? { ...baseEntry, sessionFile: fallbackSessionFile }
: baseEntry;
const sessionFile = resolveSessionFilePath(sessionId, entryForResolve, {
agentId: params.agentId,
sessionsDir: params.sessionsDir,
});
---
{
"sessionId": "f198e48b-84e6-4695-aabc-c4fed74d7cd1",
"sessionFile": "/data/agents/main/sessions/34db8152-a3ac-4e7a-8c4a-9a38d9525339.jsonl",
"updatedAt": 1775904199350
}RAW_BUFFERClick to expand / collapse
Summary
agents.defaults.heartbeat.isolatedSession: true is documented as producing a fresh session (with a new sessionId and an empty transcript) on every heartbeat run, but in practice it only rolls the sessionId in the store entry — the persisted sessionFile path is preserved via a spread, so every run keeps appending to the same physical transcript file forever. Over time the file accumulates the full history of every prior heartbeat, and each new run sees all of it in its in-context window, which is the exact opposite of isolation.
This is provable from the code alone without any production evidence.
Docs intent
Both docs/gateway/heartbeat.md and docs/gateway/configuration-reference.md describe the same behavior. Direct quotes from the repo:
docs/gateway/heartbeat.md:42—isolatedSession: true, // optional: fresh session each run (no conversation history)docs/gateway/heartbeat.md:227—isolatedSession: when true, each heartbeat runs in a fresh session with no prior conversation history. Uses the same isolation pattern as cron sessionTarget: "isolated". Dramatically reduces per-heartbeat token cost. Combine with lightContext: true for maximum savings. Delivery routing still uses the main session context.docs/gateway/heartbeat.md:441—Use isolatedSession: true to avoid sending full conversation history (~100K tokens down to ~2-5K per run).docs/gateway/configuration-reference.md:1240—when true, each heartbeat runs in a fresh session with no prior conversation history. Same isolation pattern as cron sessionTarget: "isolated". Reduces per-heartbeat token cost from ~100K to ~2-5K tokens.
The ~100K → ~2–5K promise only makes sense if each run actually starts from an empty transcript.
Code walk — why the bug is provable without runtime evidence
Step 1: heartbeat-runner.ts passes forceNew: true unconditionally
src/infra/heartbeat-runner.ts:808-824:
if (useIsolatedSession) {
…
const cronSession = resolveCronSession({
cfg,
sessionKey: isolatedSessionKey,
agentId,
nowMs: startedAt,
forceNew: true,
});Where useIsolatedSession = heartbeat?.isolatedSession === true. So when our config sets isolatedSession: true, forceNew is always true.
Step 2: resolveCronSession generates a new sessionId but preserves the old sessionFile via spread
src/cron/isolated-agent/session.ts (abbreviated to the relevant branch):
if (!params.forceNew && entry?.sessionId) {
// reuse-or-roll logic
} else {
// No existing session or forced new
sessionId = crypto.randomUUID(); // ✓ new id
isNewSession = true;
systemSent = false;
}
…
const sessionEntry: SessionEntry = {
// Preserve existing per-session overrides even when rolling to a new sessionId.
...entry, // ← this carries sessionFile forward
sessionId, // ← overridden
updatedAt: params.nowMs,
systemSent,
// When starting a fresh session (forceNew / isolated), clear delivery routing…
...(isNewSession && {
lastChannel: undefined,
lastTo: undefined,
lastAccountId: undefined,
lastThreadId: undefined,
deliveryContext: undefined,
// sessionFile is intentionally NOT in this clear list
}),
};The isNewSession cleanup block clears delivery-routing state but not sessionFile. The returned entry has a new sessionId and the OLD sessionFile.
Step 3: resolveSessionFilePath prefers persisted sessionFile over recomputing from sessionId
src/config/sessions/paths.ts:263:
export function resolveSessionFilePath(
sessionId: string,
entry?: { sessionFile?: string },
opts?: SessionFilePathOptions,
): string {
const sessionsDir = resolveSessionsDir(opts);
const candidate = entry?.sessionFile?.trim();
if (candidate) {
try {
return resolvePathWithinSessionsDir(sessionsDir, candidate, { agentId: opts?.agentId });
} catch {
// Keep handlers alive when persisted metadata is stale/corrupt.
}
}
return resolveSessionTranscriptPathInDir(sessionId, sessionsDir);
}Because the entry always has a sessionFile after the first-ever run, the if (candidate) branch is taken and the function never falls through to computing a fresh path from sessionId.
Step 4: resolveAndPersistSessionFile fallback is also gated on !baseEntry.sessionFile
src/config/sessions/session-file.ts:17-27:
const baseEntry = params.sessionEntry ?? sessionStore[sessionKey] ?? { sessionId, updatedAt: Date.now() };
const fallbackSessionFile = params.fallbackSessionFile?.trim();
const entryForResolve =
!baseEntry.sessionFile && fallbackSessionFile
? { ...baseEntry, sessionFile: fallbackSessionFile }
: baseEntry;
const sessionFile = resolveSessionFilePath(sessionId, entryForResolve, {
agentId: params.agentId,
sessionsDir: params.sessionsDir,
});fallbackSessionFile is only used when !baseEntry.sessionFile. Same gate — stale sessionFile wins.
Step 5: heartbeat-runner.ts' own cleanup does not rotate the current file
src/infra/heartbeat-runner.ts:825-861 — the archiveRemovedSessionTranscripts call only processes files from removedSessionFiles, which is populated exclusively from staleIsolatedSessionKey (the separate :heartbeat:heartbeat suffix-collapse case). It never touches cronSession.sessionEntry.sessionFile even though that file has, from the runner's perspective, been logically "rolled". So the old transcript stays on disk and stays in the store entry.
End-to-end consequence
After the first run that ever creates the heartbeat session entry:
sessionIdrolls on every invocation ✓sessionFileis frozen forever ✗- The transcript writer appends every new run's messages to the same physical file
- The transcript reader loads the whole file on every run, so the model sees all prior runs as in-context history
"Fresh session per run" does not hold for any run past the first. lightContext: true's documented ~100K → ~2–5K token savings silently regresses as the file grows.
Forensic evidence from a live deployment
This was caught on a production heartbeat agent running 15-minute ticks with isolatedSession: true, lightContext: true.
sessions.json entry for agent:main:main:heartbeat:
{
"sessionId": "f198e48b-84e6-4695-aabc-c4fed74d7cd1",
"sessionFile": "/data/agents/main/sessions/34db8152-a3ac-4e7a-8c4a-9a38d9525339.jsonl",
"updatedAt": 1775904199350
}Three different UUIDs are observable across one logical session:
34db8152…— the filename (set when the file was first created, never rotated)cbc883fc-6486-40d2-b0d1-6a102861f5df— the session id written into the transcript header (original first run,timestamp: "2026-04-10T22:09:51.937Z")f198e48b…—sessionIdcurrently in the store (generated by the most recentforceNew)
File stats after ~13 hours of 15-minute heartbeats:
| metric | value |
|---|---|
| lines | 390 |
| size | ~1.05 MB |
| distinct session records in the file | 1 |
| occurrences of the acknowledgment sentinel string | 87 |
| oldest transcript entry | 2026-04-10T22:09:51Z |
| newest transcript entry | 2026-04-11T10:43:04Z |
The model began few-shot-learning from its own ~87 prior responses on every run. Thinking traces reference the accumulated precedents as if they were protocol ("per the protocol", "the standard response") — it is following patterns set by a polluted transcript rather than the heartbeat prompt.
Impact
isolatedSession: truesilently does nothing after the first run. Every existing deployment that relies on it has been running without isolation.lightContext: true's documented token savings are optimistic by ~20x. The ~100K → ~2-5K figure only holds on the first run; every subsequent run incurs the full accumulated transcript.- Model behavior drifts toward the reinforced pattern. Any acknowledgment, summary, or tool-call sequence from an early run gets few-shot-learned by later runs and becomes sticky — even after config or prompt changes intended to alter the behavior.
- Context-overflow cliff. On a long-running deployment the file eventually exceeds the model's context window. Compaction on a transcript that is mostly tool-call noise fires
compaction-safeguard: no real conversation messages to summarizeand only writes a boundary marker, giving little real relief. - No user-visible workaround. There is no chat/CLI command that resets a non-current session, so affected users have to
rmthe file by hand from the pod's filesystem.
Suggested fix
Add sessionFile: undefined to the isNewSession cleanup block in src/cron/isolated-agent/session.ts, right next to the existing delivery-routing clears. When the entry is returned with sessionFile undefined, resolveSessionFilePath correctly falls through to resolveSessionTranscriptPathInDir(sessionId, …) and a fresh transcript file is created for the new sessionId.
A PR with the one-line fix plus three regression tests (clears sessionFile when forceNew is true, clears sessionFile when session is stale, preserves sessionFile when reusing fresh session) is incoming from alexander-applyinnovations/openclaw:fix/heartbeat-isolated-session-file-rotation.
Related
- #64196 — the llama.cpp overflow detection fix that ended up masking how severe the transcript accumulation is; without that fix the same deployment was wedging silently on raw 400s instead of compacting into noise.
AI-assisted
- Drafted with Claude Code (Claude Opus 4.6, 1M context), reviewed and verified by the author.
- Code walk reviewed line-by-line against
mainat the time of filing.
extent analysis
TL;DR
The issue can be fixed by adding sessionFile: undefined to the isNewSession cleanup block in src/cron/isolated-agent/session.ts to ensure a fresh transcript file is created for each new session.
Guidance
- Review the
src/cron/isolated-agent/session.tsfile and addsessionFile: undefinedto theisNewSessioncleanup block to fix the issue. - Verify that the fix works by checking that a new transcript file is created for each new session and that the old transcript file is not appended to.
- Test the fix with regression tests, such as
clears sessionFile when forceNew is true,clears sessionFile when session is stale, andpreserves sessionFile when reusing fresh session. - Consider reviewing related issues, such as #64196, to ensure that the fix does not introduce any new problems.
Example
if (isNewSession) {
// ...
sessionFile: undefined, // add this line to fix the issue
// ...
}Notes
- The fix is specific to the
src/cron/isolated-agent/session.tsfile and may not apply to other parts of the codebase. - The issue is caused by the
sessionFilenot being cleared when a new session is created, resulting in the transcript file being appended to instead of rotated.
Recommendation
Apply the suggested fix by adding sessionFile: undefined to the isNewSession cleanup block in src/cron/isolated-agent/session.ts. This fix is specific to the issue described and should resolve the problem of transcript files not being rotated correctly.
Vote matrix · Quick signals
Still need to ship something?
×6Another batch ranked right after the header list — different links, same matching logic.
TRENDING
- Feature Request: Configurable per-minute rate limiting (RPM) for models to prevent 429 errors
- Android: Hermes App + Termux install share ~/.hermes and cause silent permission loops
- hermes update emits unicode-animations ANSI demo in non-interactive logs
- hermes update downgrades aiohttp from 3.13.4 to 3.13.3
- npm install warns about deprecated @babel/plugin-proposal-private-methods
- DingTalk inbound media URLs are skipped as unreadable native image paths
- fix(dashboard): ChatPage clears header action buttons on ALL pages, not just Sessions
- [Bug]: check_web_api_key() hardcodes built-in backends — third-party web search plugins silently disabled
- Hermes Web UI 修复经验:GatewayManager 补丁、进程 D 状态、数据库升级问题
- Telegram gateway can silently drop turn after /stop with response=0 chars while internal work continues
- Bug Report: v0.14.0 上下文污染 — 历史回复碎片回注到新请求
- Bug: hermes skills search table truncates Identifier column — install fails with copied value
- [skills-index-watchdog] Skills index is stale or degraded (degraded)
- Discord approval embed not rendering on web/mobile — embed data present in API but invisible
- Idea: Discord voice-channel participation / opt-in auto-join mode
- [Feature]: Claude Code--ultrawork
- build-arm64 job deterministically fails on cold cache (Azure SAS token expires mid-build)
- [Enhancement] computer_use: action=type should fall back to key events for terminal emulators (Ghostty/Terminal.app/iTerm2)
- Feature Request: Session Recovery on Temporary Provider Outage
- [Bug]: Hermes dashboard not working on NixOS (container)
- [Feature]: Add option to ignore @all/@everyone mentions in Feishu group chats
- QQ Bot WebSocket 频繁断开:长时间工具执行阻塞 asyncio 事件循环导致心跳超时
- patch tool: new_string escape sequences (\t) get written literally
- Feature Request: i18n / 多语言支持(国际化)
- Bug: web_crawl schema lets models auto-guess "instructions" instead of asking the user via clarify
- feat: `!command` prefix for direct shell execution (like Claude Code)
- Expose currently-running cron jobs via /api/jobs (or new endpoint)
- [Bug]: Kanban parent-child handoff: scratch workspace GC destroys artifacts before child can read them
- [Bug, Windows] hermes gateway restart loses session context — planned_stop_marker not written before SIGTERM
- [Bug]: Codex→DeepSeek fallback sends assistant turns without reasoning_content → HTTP 400 (require-side cross-provider failover)
- [Bug]: Update got stuck half way, reboot it, then ModuleNotFoundError: No module named 'hermes_cli'
- Kanban dispatcher corrupt-board handling and multi-profile gateway ownership ambiguity
- Gateway can resend a short fallback message when the real final Telegram response was already delivered
- [BUG] Bedrock: Fix 'Invalid API Key format' for presigned URL tokens
- Secret redaction corrupts code syntax in tool output (write_file, execute_code, terminal)
- Unable to connect Ollama Cloud with Pro Subscription to Hermes
- feat: fuzzy substring matching for /skill autocomplete
- PRD: Autonomous market-impact prediction briefing system
- Kanban dashboard should support task/card deep links
- [Feature] Native Feishu CardKit Streaming: consolidate best-in-class implementations
- [Feature]: Inject mental model into context when using Hindsight
- Interactive CLI hides tool output despite display.tool_progress=all, and hermes chat -v does not restore it
- fix(api_server): _handle_responses drops text.format JSON schema — structured output constraints silently ignored
- state.db FTS corruption goes undetected — no integrity check, no repair path
- bug: fallback routing can select text-only models for image requests and hide the primary failure
- feat(kanban): persist worker session_id per run and pass --resume on respawn after unblock
- feat(kanban): support GitHub/OMO lifecycle bridge for Xiyou-style automation
- Expose update-safe TUI/composer hooks for voice transcript and composer events
- Hide or configure voice transcript status rows in editable dictation mode
- [Feature]: Per-Tool / Per-Toolset Approval Policies
- Context compression creates orphan sessions missing from state.db
- messaging platform
- feat: Add read-only / silent monitoring mode for WhatsApp adapter
- double-.hermes path mismatch, the HOME env var leak, and the fallback-notification UX problem
- Bug: Plattform-Bundle name `hermes-yuanbao` in `agent.disabled_toolsets` silently kills ALL tools in gateway path (Telegram + cron), CLI unaffected
- CLI /yolo (in-chat) does not bypass dangerous command approvals — env var freeze + missing enable_session_yolo call
- OpenAI Codex provider crashes with "'NoneType' object is not iterable" (HTTP None)
- DEEPSEEK_API_KEY blocked by env blocklist in gateway process — cron jobs fail with deepseek provider
- fix(feishu): Card action callback routing issues - invalid message_id and unrecognized /card command
- Discord plugin: profiles without explicit `discord:` block silently get `require_mention=true` + `auto_thread=true` (regression in cc8e5ec2a)
- [Bug]: DISCORD_ALLOWED_ROLES ignored by gateway _is_user_authorized — role-authorized users get 'Unauthorized user' rejection
- [Bug]: /new, /clear, and /reset commands freeze the terminal session
- openai-codex subscription backend returns HTTP 200 with response.output=None, causing Slack/cron failures
- RFC: Centralized Model/Provider Registry
- bug: openai-codex provider — TypeError: 'NoneType' object is not iterable on every request (gpt-5.5)
- [Feature]: Source-aware instruction gate — architectural mitigation for indirect prompt injection
- Named custom provider stale_timeout_seconds ignored because runtime provider is normalized to `custom`
- guard test (ignore)
- [Feature]: per-platform LLM request_overrides (extra_body / reasoning_effort / service_tier)
- One-shot smoke: add Flue-backed orchestration fixture
- Gateway should not treat stale Codex app-server progress as final response after post-tool silence
- `docker_run_as_host_user: true` breaks bundled skills: Hermes home is mounted into `/root/.hermes` but the container runs as a non-root user (`HOME=/home/pn`)
- [Bug]: gateway api_server streaming bypasses server-side tool-call loop when chat_template_kwargs.enable_thinking=false (model emits tool name as plain text)
- [Feature]: Pre-install python-telegram-bot in Umbrel Hermes Docker image
- YouTube Shorts filter not working in youtube-content skill
- v0.15.0 PyPI release breaks ALL platforms — plugin.yaml manifests missing from package
- RFC: On-demand tool/skill/MCP discovery — decouple schema registration from process lifecycle
- Pixshelf: local-first stock photo workflow command center
- [Bug]: baoyu infographic skill should not silently bypass image_generate
- Pixshelf v1.5: manual submission tracking for stock agencies
- `hermes config set` silently accepts unknown keys, writing them where the runtime never reads
- Honcho memory prefetch hang on fresh CLI subprocess in v0.15.0 (regression from #27190)
- [Bug] v0.15.0 Docker image: stage2-hook.sh, main-wrapper.sh missing; container_boot module removed
- Feature: Reduce cache-read token overhead for DeepSeek providers — configurable cache_ttl, skills snapshot trimming, memory compaction
- Windows: three bugs from daily use (plugin discovery, gateway exit code, Unicode decode
- holographic memory: HRR silently degrades to FTS5 when numpy is missing
- Make max_tokens configurable for aux vision calls
- Conversation compression desynchronizes session ID between agent context and gateway routing, causing silent message loss
- [Bug]: v0.15.0 Docker image:The TUI cannot be used in the dashboard.
- cron: skip_memory=True blocks fact_store/memory tools from all cron jobs
- TUI: Node.js OOM crash when agent uses browser tools repeatedly
- feat: model_profiles — per-model toolset and memory config
- Automatic background skill patching disrupts active sessions (severe impact on local models)
- ensure_hermes_home() creates root-owned dirs in profile subdirectories when kanban workers are dispatched
- Feature: opt-in webhook bypass for DISCORD_ALLOW_BOTS — allow operator-initiated probes without weakening bot-loop guard
- v0.15.0: Codex requests fail HTTP 400 when participant display_name contains non-ASCII (emoji breaks input[].name pattern)
- Architecture: State Persistence Precedence (Memory vs Skills vs Hooks)
- [Bug]: cronjob tool: create action always fails with "schedule is required for create" even when parameters are provided
- codex-oauth: 'NoneType' object is not iterable in _run_codex_stream (gpt-5.5) — every turn fails non-retryably
- Docs/Config: Plugin local scope enablement ambiguity
- [Bug]: CLI freezes after using /new command (WSL)
- Profile Codex auth can ignore global credential pool when local state is stale
- [workflow-engine] CRITICAL: variable substitution crashes on regex metachars in user input
- [workflow-engine] HIGH: loop and bash nodes leak subprocesses on timeout
- [workflow-engine] HIGH: README documents config env vars the engine never reads
- [workflow-engine] MEDIUM: workflow_run rate limit bypassable via concurrent calls (TOCTOU)
- [workflow-engine] chore: manifest gaps, side-effectful register(), dead code, unauth kanban dispatch
- [mcp_lazy] HIGH: synthetic mcp_server_<name> stub collides with a real MCP server named 'server'
- [mcp_lazy] HIGH: promote_server eager flag documented but never persisted
- [mcp_lazy] MEDIUM: _prev_mode dict leaks and goes stale; not cleared on session evict
- [mcp_lazy] MEDIUM: get_pool has unlocked check-then-set race on pool creation
- [mcp_lazy] MEDIUM: pre_tool_call gives no guidance for unpromoted server-stub calls
- [mcp_lazy] chore: undeclared pre_tool_call hook, nonexistent 'mcp_load_tools' name in docs, missing tests
- [a2a_fleet] CRITICAL: server never auto-starts — register() runs outside an event loop
- [a2a_fleet] CRITICAL: auth_required defaults to false on a cross-machine surface
- [a2a_fleet] HIGH: remove invented disable() hook — loader never calls it, port leaks on reload
- [a2a_fleet] HIGH: plugin.yaml missing kind / provides_tools / requires_env (token env undeclared)
- [a2a_fleet] MEDIUM: tighten wide-open CORS, anonymous /health peer leak, and peer-URL SSRF
- [a2a_fleet] MEDIUM: relocate tests to tests/plugins/ and cover sync-register + auth-default paths
- xai-oauth auxiliary client incorrectly uses Responses API (CodexAuxiliaryClient), causing 403 on compression/vision/web_extract
- [Bug]: Direct Copilot gpt-5.5 large resumes are killed by 12s Codex TTFB watchdog
- [Bug]: `hermes uninstall` does not work on Windows
- TUI: Thinking block leaks raw JSON and Σ character
- Hostinger VPS: migration Hermes Agent → Hermes WebUI impossible (tini + UID mismatch + sessions)
- /goal judge over-continues exploratory goals unless the assistant explicitly says the goal is complete
- /goal auto-continuation can be amplified by preflight compression/session split and resurrect stale task state
- Dashboard infinite reload loop in loopback mode — GET /api/auth/me returns 401 on every page load
- [Bug]: Provider/LLM switch leaves stale encrypted_content causing 400 errors on Telegram sessions
- [Bug]: Infinite reload loop / React state loop on Sessions tab (Firefox + Chrome) — repeated 401 on /api/auth/me (v0.15.0)
- show_reasoning should work independently of streaming in CLI mode
- Feature Request: Strip reasoning/<think> blocks from TTS preprocessing
- mcp add / mcp test raise NameError when mcp package not installed
- v0.14.0 dashboard breaks behind reverse proxies — two regressions
- Skills hub creates empty category directories when no skills installed
- [Bug]: Custom endpoint: ChatCompletions returns content, but Hermes treats response as empty (v0.14.0)
- fix: atomic_replace() fails with EXDEV when HERMES_HOME is a cross-filesystem symlink
- fix(gateway): Feishu session cancellation orphans session guard, permanently blocking messages
- Custom endpoint pricing can overestimate Crof qwen3.5-9b cost by 1,000,000x
- MCP OAuth callback: module-level port global causes port collisions and structural weaknesses vs upstream
- Bug: send_message tool bypasses validate_media_delivery_path security check
- Proposal: Add Mnemosyne to official memory provider documentation
- feat(swarm): support custom verifier/synthesizer body + skills
- Template conversion failed
- Error occurred in the operation of the agent node in the workflow.
- PubSub client overrides Sentinel client when REDIS_USE_SENTINEL is enabled
- Frontend description of the Retrieval node output does not match the actual output
- JSON type input var raise Intenal server error
- cannot extract elements from a scalar
- 负载均衡 为模型配置多组凭据,并自动调用,此功能无法选择
- add models is error
- panic: could not create filter
- Persist partially generated messages when /chat-messages/:task_id/stop is called
- MCP server connection fails with 403 — request never leaves Dify (SSRF proxy suspected)
- Support durable async execution backends for long-running workflow steps
- [Xiaomi MiMo] Credentials validation fails with 400 "Not supported model mimo-v2-flash" when using Token Plan endpoint (v0.0.7)
- After clicking preview on a parent-child segmented knowledge base, it shows 0 chunks
- Retrieval score differs between UI upload (.docx) and API upload (.txt) despite identical chunk content and embedding model
- gemini cli crash again
- Xbox gift card code damage
- Damage caused by the gemini cli crash
- ioctl(2) failed, EBADF (Bad File Descriptor)
- Feat: Support Bun as an alternative runtime/package manager for updates and extensions
- fatal error again!!!!
- ioctl error
- Critical Crash: ioctl(2) failed, EBADF in ShellExecutionService.resizePty
- ioctl(2) failed, EBADF
- v0.44.0 Regression: Critical crash with ioctl(2) failed, EBADF during PTY resize
- Crash on startup: ioctl(2) failed, EBADF in UnixTerminal.resize
- Crash: `ioctl(2) failed, EBADF` in `node-pty` during PTY resize on macOS
- Gemini CLI crashes with `ioctl(2) failed, EBADF` in `node-pty` during `resizePty`
- Remote Role
- ERROR ioctl(2) failed, EBADF /home/mich
- RangeError: Maximum call stack size exceeded
- EBADF Error during folder creationg broke session and terminal glitches
- MAIP / Gargoub Project - Mediterania - North Coast
- Gemini cli crash again in this morning
- ERROR ioctl(2) failed, EBADF
- Verified node install fails — Checksum verification failed (Cloud)
- The extended debugging key did not arrive during registration.
- CollaborationPane unmounts collaboration store on single-user instances, causing permanent "No network connection" state
- Workflow cannot be saved when the name contains "->" (Potentially malicious string)
- automation does not work and does not show an error
- Raj Ai Automation
- Default Data Loader: DOMMatrix is not defined error
- Feature: Per-node execution timestamp overlay on canvas during workflow run
- AI Agent + Vertex `gemini-3.5-flash`: 400 "missing thought_signature" on sequential multi-turn tool calls (post-#24982)
- PDF Loader in Pinecone Vector Store fails due to pdf-parse version conflict (v2 not supported)
- emailReadImap: add UID deduplication, batch size cap, and numeric uid enforcement
- Manual node execution fails with "Could not find a node" when autosave is disabled (N8N_WORKFLOWS_AUTOSAVE_DISABLED)
- Schedule Trigger stopped firing — workflow Published & active, manual executions succeed, no automated fires for 2+ hours
- [MCP SDK] create_workflow_from_code intermittently returns HTTP 500, often as a false negative (workflow persists anyway, causing duplicates on retry)
- Credential-load wedge: workflows using googleApi/jwtAuth credentials silently fail to execute after key rotation
- Google Sheets Trigger every minute is not working manual Execute is working sent email
- [BUG] Plugin marketplace MCP connector remains stuck "still connecting" when mcp-remote requires OAuth
- [redacted at user request]
- Opus 4.7 behavioral regression: loaded instruction-following discipline degraded in recent Claude Code/Cowork updates
- [BUG] Tailscale via Homebrew CLI + Mac App Store GUI, both Macs on macOS, Cowork blocked by VPN detector despite Tailscale being a mesh VPN with no traffic interception
- stopShellPty on tab switch kills active sessions (exit 143) — regression in May 27 build
- [BUG] Long URLs are broken into multiple lines and become unclickable in terminal output
- [BUG] claude rm/stop/reap SIGKILLs background session tree without SIGTERM grace, orphaning git index.lock and similar
- [BUG] Default git workflow in the system prompt was pushed without context or consent
- [MODEL] Inconsistent output quality / Ignoring instructions (overfitting and inappropriate repetition of Korean vocabulary)
- You've hit your weekly limit · resets May 31 at 5pm (Asia/Shanghai)
- Paid yearly subscription silently downgraded to Free with no user action
- [Regression v2.1.153] Plugin bash hooks fail with "echo: write error: Permission denied" on Windows (claude-mem, shell: "bash")
- [BUG] Connector toggles in conversation are not clickable — must click text label instead
- [remote-control] Input from mobile app/browser not reaching host session — output works fine
- Model fails to read/reference CLAUDE.md contents despite being loaded in context
- [BUG] Claude Desktop reinstall destroys Code chat history (transcripts + Recents) while regular Chat history, project files, and memory all survive
- Bypass mode clamps to Accept Edits even with the toggle ON (Claude Code Desktop 1.9255.2 / CC 2.1.149)
- [BUG] TUI input freezes randomly mid-typing — entire prompt becomes unresponsive for minutes
- [BUG] Cowork downloads Linux ELF binary instead of macOS binary on macOS Sonoma 14.8.7 — exit code 132 (SIGILL) on every session
- [Feature Request] Persistent project memory — sessions forget everything on close, forcing users to keep many sessions open
- [Bug] Thread context stale after sleep/resume, returns outdated date and calendar data
- [FEATURE] Add context window usage indicator and warning before auto-compaction
- [BUG] Dictation error: Invalid character in header content ["x-config-keyterms"] on Windows
- [Bug] Anthropic API Error: Server rate limiting despite normal usage
- Does delegating work to `claude -p` subprocesses reduce context accumulation in the parent session?
- [BUG] Claude Code hangs on M1 Mac when terminal says "opening browser to sign in" and browser opens
- [BUG] Claude_Preview MCP preview_start spawns dev server with main-repo cwd instead of session's worktree cwd
- [Bug] Anthropic API Error: Server rate limiting during request execution
- [Bug] Anthropic API Error: Server rate limiting on concurrent requests
- [Bug] Ultraplan ready notification fires before cloud agent completes execution
- [BUG] API 500 ERROR ALL THROUGHOUT THE DAY
- [BUG] Cowork: Live Artifacts folder path changed in 1.9255.2, no automatic migration from Documents\Claude\Artifacts
- [Bug] Auto-compact never triggers despite statusline reporting "100% context used" (v2.1.153, Max sub, 200K mode)
- [BUG] [Desktop / macOS] 'Open in → New Window' detached session: font renders smaller than main, no per-window controls, Cmd+/Cmd- keystrokes routed to main window instead
- Feature request: option to switch between classic and new minimal UI
- [Feature Request] Show timestamps for each message
- [BUG] Terminal corruption when permission prompt appears while navigating Agent Teams agent selection menu
- [FEATURE] Allow users to customize the background color of the Claude desktop app beyond the current light/dark theme presets.
- [BUG] Statusline not displaying on Windows [fixed]
- Background agent UI Stop button is a no-op for stuck agents — process keeps consuming tokens
- Background agents silently die on session pause/resume — no completion notification, no work recovery
- Add option to hide email address from welcome banner
- [BUG] SSH Remote: `projects` field in remote ~/.claude.json becomes null after desktop restart — jsonl files intact, UI shows 'No messages yet' for every session
- [Bug] Claude Code not applying fixes despite claiming to complete tasks
- billing is unfair and poorly documented
- [BUG] Claude Code on the web: declared plugins inactive on first session, require restart to fully load
- [BUG] Restore from archive deleted sessions instead of restoring them
- [BUG] M365 connector fails with AADSTS50011 in Cowork — localhost vs 127.0.0.1 redirect URI mismatch
- claude agents: workflow slash-commands missing from dispatch-input completion (regression-adjacent to #61424)
- Claude Desktop's Info.plist missing TCC usage strings, blocks all EventKit-based MCP servers
- False-positive safety blocks on self-administered governance amendments — request for owner-authority mode for verified professional users
- [BUG] Stop pushing "AUTO"-mode
- [DOCS] Plugin marketplace guide omits `skipLfs` option for git-based sources
- [DOCS] MCP docs omit combined startup notification for MCP server and connector authentication
- [DOCS] Agent view docs omit macOS Privacy & Security identity for background agents
- [DOCS] Npm update docs do not explain release-channel behavior for `claude update`
- [DOCS] Agent SDK docs omit `subagent_type: "claude"` worktree and output persistence behavior
- [DOCS] Background session docs omit `$CLAUDE_JOB_DIR` temp-file behavior
- [FR] mask env-var values in 'claude mcp get <server>' output
- [FR] subagent worktrees should not inherit stale local 'user.email' from prior dispatches
- [BUG] Windows: Grep tool leaks rg.exe + conhost.exe processes (~2000 zombies / 14 GB RAM in long sessions)
- [BUG] Stats dashboard "Peak hour" appears off by one hour
- [BUG] Diff highlight (teal SGR background) bleeds past changed text in 2.1.150–2.1.153
- [FEATURE] confirm before deleting session
- Plugin PostToolUse hooks still silently skip in Claude Desktop / Cowork (re-filing closed #51904)
- /code-review skill: silent fallback to main...HEAD reviews other people's commits, and JSON-only output is hard to read
- Monitor tool doesn't source the shell snapshot like Bash does; PATH-dependent tools (jq, sleep, etc.) fail in Monitor commands on macOS/Nix
- [Bug] Long input lines truncated with ellipsis while typing instead of wrapping in terminal UI
- [FEATURE] VS Code extension: Render submitted user messages as Markdown in chat
- OSC 52 copy from Claude TUI doesn't reach clipboard inside tmux (regression in 2.1.146–2.1.153)
- [BUG] RemoteTrigger create/update returns HTTP 400 with circular error: "event_type is required" / "unknown field event_type"
- [BUG] Option to hide or minimize the built-in "status footer" (multi-line debug/cost panel) [re-raise of #31475]
- [Bug] Feedback submissions being closed without review or action
- [FEATURE] Word-jump cursor navigation in Chat input (option+arrow / bindable actions)
- [FEATURE] ! shell mode: filesystem tab completion
- [BUG] API Error: Usage credits required for 1M context
- claude agents: OSC 52 clipboard emission broken in tmux (regression in 2.1.146–2.1.153)
- CLI crashes on macOS 15 M3 - exit code 1
- [FEATURE] Support Cmd+V image paste from clipboard
- [FEATURE] Enhance claude.ai M365 connector to support MS Planner
- [BUG] Slash command autocomplete hijacks pasted absolute file paths starting with /
- PreToolUse hook `if` filter false-positives on complex Bash commands
- [BUG] Diff panel hangs/whites out
- Feature Request: Support drag-and-drop for binary documents (.wps, .doc, .docx, .xlsx, .pdf) in VS Code extension
- [BUG] activation of 1M context in VSCode
- [FEATURE] Support i18n / language localization for built-in slash command outputs
- Ctrl+V para colar imagens deixou de funcionar no CLI (Windows, PowerShell)
- [FEATURE] Please add Norwegian (Bokmål/Nynorsk) language support to the Claude Code interface
- [BUG] OTel log events (claude_code.user_prompt, api_request_body, tool_decision, hook_execution_complete) emitted with empty trace_id/span_id while sibling spans correlate correctly
- [BUG] Cowork crashes on every message, no VM logs generated, missing AppData\Roaming\Claude
- [FEATURE] first-class session handoff + per-session token budgets for unattended runs
- [FEATURE] Smart paste: convert clipboard code to file reference chips (like Cursor)
- [Feature Request] Restore chat pin functionality to title chat submenu
- [BUG] SIGILL issues with version 2.1.153
- [BUG] Cowork plugin upload fails with generic "Plugin validation failed" when a `description` field in any SKILL.md frontmatter contains angle brackets (`<…>`)
- [BUG] Desktop App 2.1.144+: startup scanner deletes cliSessionId from claude-code-sessions local files on every launch — session not found on disk
- [Feature Request] Add keyboard shortcut to copy last message with proper formatting
- [MODEL] Opus 4.7 not 1M
- Allow naming/renaming background agents in `claude agents` view
- Stale worktrees in .claude/worktrees/ are never cleaned up, consuming massive disk space
- Agent worktrees are never cleaned up, silently consuming disk space
- Subagent worktrees not auto-cleaned when reviewer writes scratch files
- [Bug] Skill initialization hangs for extended duration in Plan Mode
- Claude Desktop writes malformed registry Run entry (nested escaped quotes) - crashes Windows Task Manager and other Run-key parsers
- IME candidate window shows at bottom-right corner instead of caret position (Windows CMD)
- [BUG] Pressing 'Escape' doesn't close the /BTW conversation when the main conversation is asking for approval
- [BUG] Opus 4.7 (1M) intermittently emits empty-string values for tool_use.input fields, killing the session
- FleetView agent UI shows "running" with incrementing elapsed time after agent has returned
- /doctor flags context-scoped cmd+c binding as macOS conflict (false positive)
- [BUG] Text Rendering in Elvish
- Desktop app: Bypass Permissions mode flips to Accept Edits on first prompt (M5 / macOS 26.5)
- [Workaround] Date-Weekday Verification Hook — Prevents Claude from writing wrong weekdays
- [BUG] Claude Code create c:/memfs directory without asking me.
- [BUG] Claude Code's Bash execution waits forever with no processes running
- [BUG] usage stays stuck waiting for 5 hr limit after upgrading to premium seat in team plan
- [Workflow tool] resume cache is unreachable for nontrivial workflows because LLM dispatchers can't transcribe args byte-exactly
- Code review (Preview): "Add a repository" shows no results for private GitHub org repos
- [BUG] /context commands blows up context
- [Feature Request] Add precache expiry hook to enable proactive compaction before token eviction
- [BUG] Context indicator shows 0% at session start despite ~20K+ tokens already loaded
- [Feature Request] Add semantic search for --resume session history
- [Feature Request] Add session search, tagging, and filtering capabilities
- [BUG] Cowork Dispatch reports "desktop not available" on Windows 11 while standard Cowork works normally
- [Bug] Claude Code provides incorrect suggestions with high confidence despite errors
- defaultMode: acceptEdits silently overrides per-path permissions.ask rules for Write/Edit
- [FEATUR configurable tip interval (e.g. tipIntervalSeconds: 30 in settings)E]
- Plugin marketplace fails to load: schema rejects 'displayName' key (v2.1.153)
- claude agents: in-session copy uses broken OSC 52 path while overview correctly uses tmux buffer
- [BUG] Plugin agent descriptions (and custom agents) load unconditionally into context — no parity with disable-model-invocation for skills
- Crashed ultrareview consumed a free credit despite producing zero findings
- [Bug] Character rendering issue - invisible or missing text display
- [BUG] Cowork: processo Claude Code encerra com código 3 — .claude.json não contém token de autenticação (Windows 11 25H2)
- [BUG] 2.1.153 silently discards tools/list response from rmcp 0.12.0 HTTP MCP server (works in 2.1.152, wire-identical handshake)
- VS Code extension: option to auto-resume last session when reopening a workspace folder
- [Bug] Conversation continuation failure
- [BUG] Cowork crashes every time I start a new chat or attempt to continue an existing one in any project. The error displayed is: "Claude Code è andato in crash
- [Bug] Unannounced quota changes
- Native update/install fails with 'socket connection was closed unexpectedly' behind proxy — undici TLS incompatibility
- [BUG] Session name reverting after manual change
- [BUG] 非正常思考,上下文过长时,一直显示思考,点击interrupt按钮失效
- Honor `tools:` frontmatter when an agent is invoked via `@mention` — strip `Task` only when the agent did not declare it
- macOS TCC popup still recurring on v2.1.153 — "2.1.153" would like to access data from other apps
- Claude Code leaks pty handles — exhausts pseudo-terminals on macOS after long session
- [Bug] Agent fails to execute or respond to user input
- [BUG] Persistent "Expecting value: line 1 column 1 (char 0)" JSON parse error after tool execution
- [Feature Request] Implement proactive unit test coverage recommendations for recurring bugs
- VS Code panel lacks status line + terminal lacks image paste in Codespaces, forcing a tradeoff
- `/powerup` only shows ~10 lessons — allow viewing the full catalog
- [Bug] Context contamination after auto-compact with unrelated email draft of Tejo/Sado Basin
- [Bug] VSCode terminal output displays corrupted text with garbled symbols
- [Feature Request] Add LaTeX/KaTeX math rendering to TUI
- [Bug] Sub-agent PR review results not validated by orchestrating agent
- Subagents on Pro 1M tier: trivial probes pass, real workloads fail at first tool call (probe-vs-workload divergence)
- Path-scoped rules and subdirectory CLAUDE.md not loaded when creating new files matching the pattern
- AskUserQuestion: cancelling during extended thinking poisons the whole session with 400 'thinking blocks cannot be modified' (2.1.153); concurrent prompts overwrite each other
- Ideas Missing from Claude Cowork Menu (Windows)
- [BUG_BOUNTY_SAFE_POC_2026] Prompt Injection RCE Test - Command Execution Proof
- [BUG] Cowork scheduled task: execution history row not showing after successful run
- Resuming an extended-thinking session fails permanently with 400 "thinking blocks cannot be modified" (transcript stores thinking text as empty but keeps signature)
- [Bug] Plugin-registered CwdChanged and FileChanged hooks don't fire (settings.json works) — v2.1.153
- Auto-archive on PR merge / branch delete — clarify autoArchiveSessions semantics or add dedicated opt-out
- `claude mcp add` echoes Authorization header value verbatim to stdout, leaks bearer tokens to terminal and session transcripts
- [BUG] Bug report — /insights skill, Claude Code The /insights skill outputs a malformed file path.
- Plugin slash commands render with '*'-inline format instead of two-column, despite matching official plugin shape
- [Bug] Unexpected long text generation without user input or goal
- [Bug] Thinking blocks causing task progression blocked without user modification
- [BUG] (Critical!) contamination by an unknown session simirlar to the report => [Bug] Context contamination after auto-compact with unrelated email draft of Tejo/Sado Basin #63137
- [Critical] Opus 4.7 Korean output degeneration — Korean grammar itself collapses in long contexts
- [BUG] Title: Autocompact buffer persists across /clear — wastes tokens for irrelevant old context
- [Bug] Auto-Compact loses user input before processing in conversation history
- Feature: per-invocation effort parameter + runtime session-config introspection for skills
- Auto-mode classifier mislabels Azure DevOps vote -5 as "Reject" when denying PR vote actions
- [BUG] Claude Desktop and Claude Code CLI never re-register MCP tools after OAuth 2.1 handshake on a remote HTTP server
- [BUG] Workspace file tags leak across sessions
- [BUG] Ink renderer crashes on Windows 11 build 26200 (Canary) duplicate banners, terminal mode leaks, mid-operation aborts
- [BUG] Claude Code Desktop issue
- PTY master fd leak in Claude desktop app exhausts macOS kern.tty.ptmx_max after ~2-3 days
- [BUG] Claude Code — Session Management after Unexpected Interruption
- [Windows] Cowork OpenTelemetry exporter does not initialize - zero events emitted to any destination, including loopback
- [Bug] Opus 4.7: 400 `thinking blocks ... cannot be modified` on long extended-thinking sessions, triggered by history-altering events (scheduled prompts / parallel tool-call cancellation)
- [BUG] API Error: Server is temporarily limiting requests (not your usage limit) · Rate limited
- Multi-plugin custom marketplace: only first plugin registered in installed_plugins.json, skills don't load
- [BUG] Git push through the SDK's git proxy fan-outs into ~500 GitHub REST API calls, exhausting the 5,000/hour budget after a handful of pushes
- [BUG] Claude took liberties it really shouldn't with my global config
- [BUG] Agent window focus lost after navigating with arrow keys, causing scroll deadlock
- [BUG] `--model` flag silently ignored in interactive sessions (works in `--print` only)
- [BUG] Dispatch permanently shows "desktop appears offline" on Windows 11 - never worked on first use
- feat: support per-command enableWeakerNetworkIsolation as safer alternative to dangerouslyDisableSandbox
- /code-review outputs a raw JSON array instead of readable findings
- [BUG] Cowork — Additional allowed domains ignored on Team plan; same domain works on Pro plan
- Haiku
- [Bug] False positive blocking beneficial outcomes in tool execution
- 3P Bedrock SSO: credentials silently expire without triggering re-auth on day 2+
- CLAUDE_AUTOCOMPACT_PCT_OVERRIDE in settings.json env block silently ignored by autocompact logic
- Auto-compaction deletes main session JSONL before verifying summary completion, causing data loss
- [Bug] Claude Code not executing stated actions or producing expected results
- [FEATURE] Deferred Messages — Queue Input for End of Turn
- [BUG] Up/Down arrows in input box navigate history instead of moving cursor — regression in 2.1.149+
- Cancelling a parallel tool-call batch corrupts thinking blocks -> 400 "thinking blocks cannot be modified" permanently wedges the session
- Claude Code caused data loss, then contradicted itself about recovery (two incidents, one session)
- [Bug] Unclear error messages from Claude Code CLI
- [Bug] Agent tool rejecting due to context size limit exceeded
- claude agents: daemon and bg-spare processes spin at ~100% CPU when idle
- [BUG] Compaction fails with "context window limit" error even when context usage is low (e.g., 20%) — regression in v2.1.153
- Remote Control entitlement lost after May 27-28 incident — `Error: Remote Control is not yet enabled for your account` on active Max subscription
- PreToolUse hook exit code 2 does not block Write tool
- [Bug] Thinking blocks in latest assistant message are immutable
- GUI: dispatch file:// and custom-scheme clicks to OS shell handler
- Show current model in statusLine by default
- [Bug] Agent console becomes unresponsive to keyboard input after multiple agents initialized
- [FEATURE] PreToolUse hooks should have a way of updating the environment
- [Bug] Unable to start or use Claude Code CLI
- [BUG] Repository not visible in Claude Code web repo picker
- Session permanently wedged on 400 "thinking blocks cannot be modified" after parallel tool_results
- [Bug] @ autocomplete loses sibling repos after a file edit in multi-repo workspace
- Unclear error message when creating sub-agent without authentication
- [Bug] Anthropic API errors causing frequent failures and high token usage
- [BUG] @ mention file picker only shows packages, not individual files (desktop app - Code tab)
- [Bug] TUI panel footer remains sticky and consumes excessive terminal space
- PR-status polling exhausts GitHub GraphQL rate limit on repos with many open PRs
- [BUG] Windows: welcome panel not shown in some project folders (2.1.153)
- [Bug] Anthropic API Error: thinking blocks corrupted during context compaction with extended thinking enabled
- API 400 "thinking blocks cannot be modified" permanently bricks session during agent activation (interleaved thinking + tool use)
- Right-click Copy copies the whole message instead of the selection; pasted text retains dark background
- Mid-session model switch corrupts conversation when extended thinking is enabled (API 400: 'thinking blocks cannot be modified')
- [BUG] Markdown file links in chat output do not open files when clicked (VS Code extension)
- Stuck retry loop: `400 thinking blocks cannot be modified` on large interleaved-thinking turns using AskUserQuestion
- [FEATURE] Prompt user for approval before auto-compaction proceeds
- Custom MCP connectors not attachable to scheduled routines — no UUID discovery path
- [BUG] Claude in Chrome — Navigation blocked for teams.cloud.microsoft and outlook.cloud.microsoft after Microsoft domain migration**
- [BUG] Claude Desktop — Personal plugins panel renders list but is entirely non-interactive (macOS, v1.9255.2)
- [Bug] error when using Workflows
- [BUG] Persistent "update available" notification despite being on latest version
- [BUG] Sweep Agent from /code-review never completes
- [Bug] Tool calls not executing or returning results
- [FEATURE] Cloud-synced memory and settings across machines
- [Bug] Terminal UI freezes when Ctrl+O view exits during interactive prompt in plan mode
- Continuous api errors when using claude code with Opus 4.7 with thinking on low
- [Feature Request] Add support for installing and using previous Claude Code versions
- [Bug] Extended Thinking: Summarized thinking blocks fail signature validation when resent to API
- [Bug] Anthropic API Error: 'thinking' blocks cannot be modified
- [Bug] Anthropic API Error: Thinking blocks cannot be modified with extended thinking mode
- Feature request: Lazy/on-demand MCP server connections
- [Bug] Tool Arguments Parsed as String Instead of Object
- [Bug] Anthropic API Error: Insufficient context provided
- [Bug] Claude Opus occasionally uses moskovian(russian) orthography instead of Ukrainian in system-prompted responses
- Opus 4.8: backgrounded task completions (subagents AND Bash) crash with 400 "thinking blocks cannot be modified"
- [Bug] Opus 4.7 fabricates stable preferences ("my default") to rationalize arbitrary choices when challenged
- [Bug] Unable to update Claude Code CLI
- [BUG] Desktop app: /remote-control mints link + connects bridge (main.log) but in-chat link/QR panel never renders
- Feature: sessionColor and sessionName in .claude/settings.json
- [BUG] Anthropic API error: thinking blocks
- [FEATURE] Support Remote MCPs in Cowork as in Claude Code
- [Bug] Anthropic API Error: 400 Bad Request with Redacted Thinking - 0 4.7 & 4.8
- [Bug] Anthropic API Error: Cannot modify thinking blocks from different model versions
- Interleaved thinking + multi-tool turn corrupts thinking block (text blanked, signature kept) → permanent 400 'blocks must remain as they were'
- [BUG] Mode/permission changes mid-tool-loop (effortLevel: xhigh) poisons entire session
- Session failure log: Opus 4.6 ignores its own rules for an entire session
- [BUG] "400 Guardrail was enabled" error when using Claude Opus 4.8 with AWS Bedrock
- [Feature Request] Add subagent approach selection option to avoid accidental feedback
- Persistent 400 'thinking blocks in the latest assistant message cannot be modified' — interleaved thinking persisted with empty text + signature bricks sessions
- [BUG] DesktopvsApp
- [BUG] Opus 4.7 cache hit rate collapse after May 27 incident — Messages 1.1k→88.9k in 9 minutes, $630/session
- [Bug] Anthropic API Error: Invalid thinking block format
- [BUG] FUCK CLAUDE
- Opus 4.8 extended thinking: Stop hook block re-entry corrupts thinking blocks → 400
- [Bug] 4.8 Fails when accessing previous model history
- [Bug] Unintended File Modifications During Execution
- [DOCS] Model configuration docs omit lean system prompt default scope and model exceptions
- Add "Always allow globally" option to permission prompts
- Server-side model upgrade (Opus 4.7→4.8) wedges in-flight sessions with `thinking blocks cannot be modified` 400
- [DOCS] AskUserQuestion docs missing multiple-choice prompt decision threshold
- [DOCS] Agent view docs omit shell-command background session launch syntax
- [DOCS] Agent view dispatch input docs incorrectly imply `/logout` dispatches as a prompt
- [DOCS] Claude in Chrome docs omit connected-browser selection behavior
- [DOCS] Plugin docs omit `defaultEnabled: false` for opt-in plugins
- Feature Request: Customizable chat text colors for user and assistant messages
- [DOCS] `/plugin` Discover tab docs omit directory-based suggested plugin pins
- VSCode Chrome integration silently fails: 3 distinct bugs
- [DOCS] MCP stdio docs omit session environment variables
- [Bug] Anthropic API error on second request within session with Claude Opus 4.8
- Cowork emits a blank session "index" handoff on focus when a CLI session is paused awaiting input
- [DOCS] MCP docs omit `claude mcp list/get` pending-approval output for unapproved project servers
- [BUG] /compact fails with 400 error when last assistant turn contains thinking blocks
- [DOCS] `/claude-api` docs omit Opus 4.8 migration guidance
- [DOCS] Fast mode docs still recommend deprecated Opus 4.6 override variable
- [DOCS] Bash tool docs omit `$TMPDIR` consistency across sandboxed and unsandboxed commands
- [Bug] Anthropic API Error: 400 Bad Request on Extended Thinking
- [DOCS] Background session docs omit worktree-isolation behavior for spawned subagents
- Built-in mechanistic self-verification of verifiable claims (symmetric to the auto permission gate)
- [DOCS] Worktree docs do not clarify `worktree.baseRef: "head"` inside linked worktrees
- [BUG] Excessive RAM usage with multiple parallel chats (~10 sessions → 30 GB memory pressure, macOS OOM)
- [DOCS] Managed MCP policy docs omit invalid `allowedMcpServers`/`deniedMcpServers` entry behavior
- [DOCS] Effort docs omit `CLAUDE_CODE_ALWAYS_ENABLE_EFFORT` unsupported-model behavior
- Regression (2.1.147–2.1.150?): resuming an extended-thinking session after a CC update/model-switch → unrecoverable 400, session bricked
- [DOCS] Windows updater docs omit `claude.exe` in-use recovery guidance
- [DOCS] VS Code auto mode docs still tie mode-picker visibility to bypass-permissions setting
- [DOCS] MCP docs omit `/mcp` tool list and detail rendering behavior
- [DOCS] Fine-grained tool streaming docs still describe provider opt-in behavior
- bypassPermissions: session startup reads flat pref, GUI toggle writes per-account pref — they never sync
- [BUG] Claude Desktop Code tab causes disk write limit violation — 8.5GB in 11 min, macOS kills app (M5, v1.9659.1)
- Ultrareview v2.1.96: docs describe /tasks command + claude ultrareview --json subcommand that don't exist; findings hard to read after completion
- I'd be happy to help create a GitHub issue title, but I don't see the error message in your message. Could you please share the specific error you're encountering? That way I can generate an accurate and descriptive issue title for you.
- [BUG] Claude in Chrome `file_upload` rejects all scheduled-task sessions with misleading error (real cause: INVALID_SESSION)
- Extended thinking: signed thinking block 'cannot be modified' (400) permanently wedges session
- RTL text support for Hebrew (and Arabic) in Claude Code
- [Bug] Random errors occurring across multiple operations