openclaw - ✅(Solved) Fix doctor falsely flags live *.trajectory.jsonl files as orphan transcripts [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities 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

Loading…
GitHub stats
openclaw/openclaw#70680Fetched 2026-04-24 05:54:46
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Participants
Timeline (top)
cross-referenced ×1

On OpenClaw 2026.4.22, openclaw doctor --non-interactive falsely reports live *.trajectory.jsonl session artifacts as orphan transcript files and suggests archiving them via --fix, even when the owning sessions are still present in sessions.json and one may have a live lock.

Error Message

  • Doctor reports orphan transcript files in ~/.openclaw/agents/main/sessions
  • Reported examples are *.trajectory.jsonl
  • At least one matching session may still be active and locked
  • openclaw doctor --fix appears willing to rename valid trajectory logs to *.deleted.<timestamp>

Root Cause

Safety note

Users should avoid running openclaw doctor --fix on this finding until the matcher is corrected, because it may rename valid trajectory logs for live or still-referenced sessions.

Fix Action

Fixed

PR fix notes

PR #70812: fix: ignore trajectory sidecars in orphan transcript scans (Fixes #70680)

Description (problem / solution / changelog)

Summary

Problem

openclaw doctor was treating *.trajectory.jsonl files as primary session transcripts. That made live trajectory sidecars show up as orphan transcript candidates.

Why it matters

When doctor --fix offers to archive orphan transcripts, it should only touch real session transcript files. Flagging trajectory artifacts here is misleading and risks renaming valid debugging data for active or recent sessions.

What changed

  • Excluded *.trajectory.jsonl from isPrimarySessionTranscriptFileName()
  • Added helper coverage so trajectory sidecars are no longer treated as primary or usage-counted transcripts
  • Added a doctor regression test that keeps a real orphan transcript candidate while proving a neighboring trajectory sidecar is ignored

What did NOT change

  • No changes to trajectory export or trajectory file naming
  • No changes to orphan cleanup behavior for actual *.jsonl transcript files
  • No new config, flags, or migration logic

Change Type

  • Bug fix

Scope

  • Session artifact classification
  • Doctor orphan transcript detection

Linked Issue/PR

Closes #70680

User-visible/Behavior Changes

  • openclaw doctor no longer reports *.trajectory.jsonl files as orphan transcript files
  • openclaw doctor --fix will not offer to archive those trajectory sidecars through the orphan transcript path

Security Impact

  • Low
  • This reduces the chance of doctor --fix renaming valid local debug artifacts by mistake

Repro + Verification

Environment

  • Local macOS worktree on branch fix/70680-ignore-trajectory-orphans

Steps

  1. Place an orphan transcript such as orphan-session.jsonl in the agent sessions directory
  2. Place a neighboring trajectory sidecar such as live-session.trajectory.jsonl in the same directory
  3. Run the doctor state-integrity check

Expected

  • Doctor should only offer archival cleanup for the real orphan transcript
  • The trajectory sidecar should be ignored by the orphan transcript scan

Actual

  • With this change, the doctor warning still catches the orphan transcript and leaves the trajectory sidecar alone

Evidence

  • Targeted session artifact tests passed locally
  • Targeted doctor state-integrity tests passed locally, including the new trajectory-sidecar regression coverage

Human Verification

  • Confirm that doctor warnings list the real orphan transcript example and do not mention *.trajectory.jsonl
  • Confirm that running the archival prompt path does not rename the trajectory sidecar

Compatibility/Migration

  • No migration needed
  • Existing transcript and trajectory files keep the same names

Failure Recovery

  • If follow-up reports show another structured sidecar should also be excluded, the same helper can be tightened again without changing stored data

Risks and Mitigations

  • Risk: another feature may have been relying on the old broad matcher
  • Mitigation: the shared helper tests now assert that trajectory sidecars are excluded, and the doctor regression test covers the user-facing failure mode directly

Changed files

  • src/commands/doctor-state-integrity.test.ts (modified, +17/-1)
  • src/config/sessions/artifacts.test.ts (modified, +3/-0)
  • src/config/sessions/artifacts.ts (modified, +3/-0)

Code Example

function isPrimarySessionTranscriptFileName(fileName) {
  if (fileName === "sessions.json") return false;
  if (!fileName.endsWith(".jsonl")) return false;
  return !isSessionArchiveArtifactName(fileName);
}

---

const orphanTranscriptPaths = fs.readdirSync(sessionsDir, { withFileTypes: true })
  .filter((entry) => entry.isFile() && isPrimarySessionTranscriptFileName(entry.name))
  .map((entry) => path.resolve(path.join(sessionsDir, entry.name)))
  .filter((filePath) => !referencedTranscriptPaths.has(filePath));
RAW_BUFFERClick to expand / collapse

Summary

On OpenClaw 2026.4.22, openclaw doctor --non-interactive falsely reports live *.trajectory.jsonl session artifacts as orphan transcript files and suggests archiving them via --fix, even when the owning sessions are still present in sessions.json and one may have a live lock.

Observed behavior

  • Doctor reports orphan transcript files in ~/.openclaw/agents/main/sessions
  • Reported examples are *.trajectory.jsonl
  • At least one matching session may still be active and locked
  • openclaw doctor --fix appears willing to rename valid trajectory logs to *.deleted.<timestamp>

Example doctor output:

  • 2b549cee-6e59-454d-8bb6-94c08d20bcbb.trajectory.jsonl
  • 67553e3e-f24d-4018-bb38-a9abc43b9d23.trajectory.jsonl
  • 69d8482d-2321-4cb0-bd7d-b59132b6f382.trajectory.jsonl

Expected behavior

Doctor should only consider primary session transcript files as orphan candidates. *.trajectory.jsonl should not be treated as orphanable primary transcripts unless they are explicitly tracked and cross-checked as trajectory artifacts.

Why this happens

isPrimarySessionTranscriptFileName(fileName) currently matches any non-archived *.jsonl, which incorrectly includes *.trajectory.jsonl.

Current matcher in dist/artifacts-Czkc6wYi.js:

function isPrimarySessionTranscriptFileName(fileName) {
  if (fileName === "sessions.json") return false;
  if (!fileName.endsWith(".jsonl")) return false;
  return !isSessionArchiveArtifactName(fileName);
}

Doctor then builds orphan candidates from that matcher in dist/doctor-state-integrity-CLk7YYo-.js:

const orphanTranscriptPaths = fs.readdirSync(sessionsDir, { withFileTypes: true })
  .filter((entry) => entry.isFile() && isPrimarySessionTranscriptFileName(entry.name))
  .map((entry) => path.resolve(path.join(sessionsDir, entry.name)))
  .filter((filePath) => !referencedTranscriptPaths.has(filePath));

But referencedTranscriptPaths is built from entry.sessionFile values from sessions.json, which point to <sessionId>.jsonl, not <sessionId>.trajectory.jsonl.

So the candidate set includes trajectory logs, while the reference set does not, creating false orphan reports.

Evidence

Live references in ~/.openclaw/agents/main/sessions/sessions.json included:

  • agent:main:upgrade69d8482d-2321-4cb0-bd7d-b59132b6f382.jsonl
  • agent:main:upgrade:heartbeat67553e3e-f24d-4018-bb38-a9abc43b9d23.jsonl
  • agent:main:cron:... / run entry → 2b549cee-6e59-454d-8bb6-94c08d20bcbb.jsonl

Corresponding trajectory files were flagged as orphan:

  • 69d8482d-2321-4cb0-bd7d-b59132b6f382.trajectory.jsonl
  • 67553e3e-f24d-4018-bb38-a9abc43b9d23.trajectory.jsonl
  • 2b549cee-6e59-454d-8bb6-94c08d20bcbb.trajectory.jsonl

A live lock was also present:

  • 69d8482d-2321-4cb0-bd7d-b59132b6f382.jsonl.lock
  • lock pid matched the running gateway process at the time of inspection

Regression shape

I checked the 2026.4.21 package as well:

  • the broad isPrimarySessionTranscriptFileName() matcher already existed
  • the orphan-detection logic already existed
  • but I could not find trajectory artifact strings in that older dist bundle

So the likely regression shape is:

  1. the matcher was already too broad
  2. 2026.4.22 introduced *.trajectory.jsonl artifacts
  3. doctor now misclassifies them as orphan transcripts

Suggested fix

Narrow isPrimarySessionTranscriptFileName() so it excludes structured secondary artifacts such as:

  • *.trajectory.jsonl

For example, require a bare primary transcript filename shape, or explicitly exclude known suffix families before .jsonl.

Safety note

Users should avoid running openclaw doctor --fix on this finding until the matcher is corrected, because it may rename valid trajectory logs for live or still-referenced sessions.

extent analysis

TL;DR

The issue can be fixed by narrowing the isPrimarySessionTranscriptFileName() function to exclude *.trajectory.jsonl files.

Guidance

  • Update the isPrimarySessionTranscriptFileName() function to explicitly exclude *.trajectory.jsonl files, for example by adding a condition to check for the .trajectory suffix before .jsonl.
  • Verify that the updated function correctly identifies primary session transcript files and excludes *.trajectory.jsonl files.
  • Avoid running openclaw doctor --fix until the matcher is corrected to prevent renaming valid trajectory logs.
  • Review the dist/artifacts-Czkc6wYi.js and dist/doctor-state-integrity-CLk7YYo-.js files to ensure the changes are correctly implemented.

Example

function isPrimarySessionTranscriptFileName(fileName) {
  if (fileName === "sessions.json") return false;
  if (!fileName.endsWith(".jsonl")) return false;
  if (fileName.includes(".trajectory.")) return false; // exclude *.trajectory.jsonl files
  return !isSessionArchiveArtifactName(fileName);
}

Notes

The suggested fix assumes that the *.trajectory.jsonl files are not intended to be treated as primary session transcripts. If this is not the case, further investigation may be needed to determine the correct behavior.

Recommendation

Apply the workaround by updating the isPrimarySessionTranscriptFileName() function to exclude *.trajectory.jsonl files, as this will prevent incorrect identification of orphan transcript files and potential data loss.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Doctor should only consider primary session transcript files as orphan candidates. *.trajectory.jsonl should not be treated as orphanable primary transcripts unless they are explicitly tracked and cross-checked as trajectory artifacts.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix doctor falsely flags live *.trajectory.jsonl files as orphan transcripts [1 pull requests, 1 participants]