Chat list ordering destroyed by batch mtime restamping of old transcripts

Status Open
Reported on v2.1.261
Maintainer reply None cached
Activity 0 comments · opened Sep 5, 2026

Summary

The VSCode extension sorts the chat history list by each transcript's file mtime. A startup pass periodically rewrites whole batches of old transcripts, flattening a full day's sessions onto a single instant. The chat I was actually last working in ends up buried among ~12 ties, and the list order no longer reflects when I used anything.

Environment

  • Claude Code 2.1.261, extension anthropic.claude-code-2.1.261-linux-x64
  • Linux (AlmaLinux 9, kernel 5.14), VSCode Remote-SSH
  • remoteControlAtStartup: false

Evidence

From ~/.claude/projects/<project>/, correlating each transcript's mtime against the real message timestamps inside it:

cluster 2026-09-01 06:37:41  ->  all 11 sessions from Aug 31 (13:13-21:50)
cluster 2026-08-24 04:01:06  ->  all 11 sessions from Aug 23 (17:46-00:18)
cluster 2026-08-21 22:18:22  ->  all 12 sessions from Aug 21 (10:24-19:42)

Each batch is every session from one working day, stamped at one moment, usually the next morning's first window open. All drift is forward, never backward, up to +20.8h, across 100+ transcripts.

It is a pure restamp, not a content write:

  • inode unchanged
  • mtime == ctime to the nanosecond
  • nothing appended — the final record is still the session's own genuine last-prompt line
  • no duplicated tail record

So the transcript content is honest; only the filesystem timestamp lies.

Why it matters

Sorting keys on a timestamp that internal bookkeeping mutates. File mtime is not a record of when the user last used a session, so any pass that rewrites the file for its own reasons destroys the ordering.

Suggested fix

Sort by the last message timestamp inside the transcript rather than by file mtime. The extension already reads each file's tail to render the last-prompt preview, so that value is available at no extra cost.

Secondary issue: retention

cleanupPeriodDays also keys on mtime, so the forward-stamping silently extends transcript retention. Retention is not "30 days since last use" but "30 days since bookkeeping last touched it".

Conversely — and this is a trap for anyone working around the bug — restoring honest mtimes makes transcripts older than the retention window immediately eligible for deletion. I had to raise cleanupPeriodDays before repairing my own timestamps to avoid losing a month of history.

View original on GitHub ↗