DeepSeek Harness new session shows old content: blank reuse
Click "new session" and you get a blank input page that looks perfectly normal; type "haha" and send it, and the screen first shows an image card generated with /image on October 20, with your new message appended after it. The UI is not rendering wrong — the new session was never created; it reused an old session treated as "blank" and seeded from it (#10889). Separate the three kinds of shell sessions first, then decide what to clear.
DeepSeek Harness: Signal 1: old content appears in a new session
If old events appear before session/end-seed, it is reuse; a genuinely blank session never has that event sitting in the middle.
- Find the session log at
~/.dsh/sessions/<workspace>/<session-id>/session.v4.jsonl.zstd. - Decompress it and read the event order: in the community case seq 3 was a
command/runfrom 10-20 and seq 4 wascommand/done. - Seq 5 was
session/end-seedat 10-24 20:33 — that is "closing the old log as a seed". - Seq 6 was the new message
agent/inbox/spliced "haha", andturn/startonly began at seq 7. - The event timestamps are the evidence: one log containing two time ranges four days apart.
DSH plugin: Signal 2: the creation time is wrong
The session header's createdAt keeps the old value, so a "new session" shows a creation time from days ago; this is the most direct reuse clue.
- Compare the creation time in the session list with the moment you clicked "new".
- In another community case the new session showed 10-17 while the actual day was 10-24.
- Those logs usually contain only three seed events:
permission/preset,sandbox/mode, andapproval/policy, with noturn/startand noend-seed. - In other words, the previous creation never finished, leaving a half-initialized record that was judged blank and reused.
DeepSeek Harness: Three shell types: why they count as blank forever
blank means "the folded prefix contains no turn", regardless of whether there is content, so all three types below stay in the candidate pool indefinitely.
| Type | What the log contains | How it happens |
|---|---|---|
| Command-only | command/run + command/done | only slash commands such as /image ran, no turn formed |
| Half-initialized | only permission/preset, sandbox/mode, approval/policy | creation never finished and end-seed is missing |
| Single-message | only one user/message | the first message was interrupted or failed |
Community measurement: an /image session and a session with only one user/message both show blank: true in sessionListMetadata. The check is written in the schema: "Whether the folded prefix contains no turn."
DSH Plugin: Signal 3: subagent model selection silently stops working
These sessions contain no subagent/model-selection-policy event, so the subagent tool carries no provider/model, while the settings page still says it only affects new sessions and the user has no way to notice.
- Open the workspace config and confirm
subagent-model-selection-settingshasenabled: trueandallowedModels. - Search the reused session for
subagent/model-selection-policy; the event is absent. - Look at the tools array in
request/header:subagenthas onlycwd,description, andprompt, with noprovider,model, orreasoning_effort, and nolist_subagent_models. - Compare a genuinely new session in the same workspace: the policy event appears at seq 3,
subagenthas the three extra parameters, andlist_subagent_modelsis present. - The root cause is that
tool-subagentdecides new sessions withfirstLiveSeq === 0; for a reused session restored from disk the first live sequence is 3 (4 after end-seed is filled in), never 0, so the policy is neither read nor written. - The policy is a one-time per-session snapshot: that healthy session snapshotted the 2 routes available then, while the current config already has 4.
DeepSeek Harness: Cleanup: find the shell sessions and move them out
There is one criterion: no turn/start in the log, but commands or user messages present.
- Quit DSH completely so nothing writes while you clean.
- Back up the whole
~/.dsh/sessionsdirectory. - Decompress each session's
session.v4.jsonl.zstd(a multi-frame zstd format, so decompress frame by frame). - Count
turn/startoccurrences: 0 withcommand/runoruser/messagepresent means a shell. - Move those directories outside the sessions root (do not delete them outright; move first and observe).
- After restarting, create a session and confirm the input page is truly blank and the creation time is now.
One more thing to check: if a reused blank session fails log validation, creation fails outright instead of skipping it. The community hit SessionQueryError: stored session ... is corrupt ... session event at seq 4 lacks an identified message, caused by an older version's user/message event having no data.id while the current version requires one. Fix the log by hand or delete that session.
DSH plugin: Fix direction and today's workaround
Core needs to change the blank check: count only "header plus default init events" as blank, and re-read the log before reuse.
- Redefine blank as "the log is empty": only a header plus
permission/preset,sandbox/mode, andapproval/policyqualify. - Or at least exclude sessions containing
user/messageorcommand/runfrom the candidate pool. - Re-read the log before reusing (
refreshProjections()currently runs only on therestoreBlankbranch, while ordinary creation uses a possibly stale cached hint). - When a "blank with content" is detected, create a new session instead of seeding the old log.
- Make the create path tolerant of one bad session: skip it with a notice rather than letting one bad log block creation.
- On the subagent side, change the freshness check to "no
turn/start", or write the policy event once on the blank-reuse path.
One-minute self-check list
Spend a minute on three checks after every new session, and you can catch shell sessions before the bleed gets bad.
- Does the creation time in the list match the moment you clicked new?
- Is the input page completely blank, with no history cards and no leftover scroll position?
- After the first message, does the log avoid an ordering where
session/end-seedprecedes your message?
If any of the three is off, move the candidate sessions out using the cleanup steps and create the session again.
Cautions
Trust the log over the blank-looking UI.
- Do not assume "the UI is blank" means a new session. The real check lives in the log, not the UI.
- Do not delete only the last one. There may be several shells; clear one and the next creation reuses another.
- Do not ignore the creation time. It is a zero-cost self-check signal.
- Back up before cleaning. Session logs hold history that cannot be recovered after a mistaken delete.
- Recheck after upgrading. The community still reproduced it on rc.3, so do not assume a version change fixes it.
If your new sessions look normal and only occasionally an old image shows up, that is still this family — the candidate pool just happened to contain one shell.See DeepSeek Harness draft lost when switching a new session for the related case.
FAQ
The old content appears because DeepSeek Harness judged that old session blank and reused it. Creating a session looks for a blank session in the same workspace and continues writing its log as a seed, so session/end-seed lands after the old events and old content shows up in the "new" session.
The check DeepSeek Harness applies is "the folded prefix contains no turn", not "contains nothing". Slash-command sessions (only command/run and command/done), interrupted first messages, and records left by failed commands all count as blank forever.
No, that creation time is not normal, and reuse causes it in DeepSeek Harness. The createdAt in the session header keeps the old value, so the "new session" displays the old session's creation time; as long as one shell session remains in the workspace, this can recur.
DeepSeek Harness skips the subagent policy in a reused session because tool-subagent decides "new session" with firstLiveSeq === 0. A reused blank restored from disk has a first live sequence equal to the existing event count, never 0, so the policy event is not written and the subagent tool carries no provider/model arguments.
Decompress the old session log and look for turn/start in DeepSeek Harness: a session with none but with command or user/message is a shell. Archive or delete those directories, and new sessions become genuinely blank again.
Related Terms
- blank session
- A blank session in DeepSeek Harness is one whose folded prefix contains no turn. The check counts turns only and ignores whether command or user/message records exist, so half-initialized records are reused as blank too.— https://github.com/deepseek-ai/deepseek-harness/discussions/10889
- session/end-seed
- session/end-seed is the seed-closing event in a session log, marking that an existing log was taken as the initial content of a new session. Appearing after old events is direct evidence that an old session was reused.— https://github.com/deepseek-ai/deepseek-harness/discussions/10889
- firstLiveSeq
- firstLiveSeq is the sequence number of the first live event in a session. tool-subagent uses it to decide whether a session is new — only 0 counts — so a reused session never receives a fresh subagent policy.— https://github.com/deepseek-ai/deepseek-harness/discussions/10889
- subagent/model-selection-policy
- subagent/model-selection-policy is the event that snapshots the models available to subagents once per session. It is written only when a session is created, and without it the subagent tool carries no provider/model arguments.— https://github.com/deepseek-ai/deepseek-harness/discussions/10889
Sources
- #10889 — a new session reuses an old session that has only commands and no turn· deepseek-ai (GitHub Discussions)
- deepseek-ai/deepseek-harness (source repository)· GitHub