[Bug]: /compact as the first message in a forked thread fails with "Cannot compact an empty thread"#24160
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Have a Claude thread with several user/assistant turns.
- Fork it from one of its runs (thread payload ends up with
forkedFrom: { type: "run", threadId: <parent>, runId: <parent run> }). - In the new fork, send
/compactas the very first message.
Expected behavior
The fork inherits the parent's conversation, so /compact should compact that inherited context, the same as /compact on the parent.
Actual behavior
The run fails immediately without reaching the provider:
Cannot compact an empty thread Start a conversation before compacting this thread.
If the fork already has at least one non-/compact user message of its own, /compact works. Only a fork whose first message is /compact hits this.
Cause
ProviderTurnStartService short-circuits /compact when !projection.hasConversation:
hasConversation only counts user messages whose thread_id is the current thread:
A fork does not copy the parent's messages. It only references them through thread.forkedFrom, and its provider thread is still pending (nativeThreadRef: null, status: "not_loaded", forkedFrom.providerThreadId set) until the first real run forks the native session. So for a fresh fork hasConversation is false even though the fork has a full inherited history.
State from an affected install (statev2.sqlite):
| thread | own user messages | /compact result |
|---|---|---|
| parent | 7 | — |
| fork (run fork of the parent) | 1 (/compact only) | "Cannot compact an empty thread" |
another fork with 4 own messages before /compact | 10 | compacted normally |
Possible fix: treat the thread as having a conversation when it has forkedFrom (or when its pending provider thread has forkedFrom.providerThreadId), or include the inherited parent messages up to the fork point in the hasConversation check. The in-memory variant at ProjectionStore.ts#L7252 has the same shape.
Impact
Minor bug or occasional failure
Version or commit
v0.1.2 (installed runtime). The same code is on main @ 66ee628.
Environment
T3 server v0.1.2 on macOS (Mac mini), desktop GUI client on another Mac connected remotely. Provider: Claude Agent (claude-opus-5-5).
Workaround
Send any normal message in the fork first so it gets its own user message and native session, then run /compact (untested beyond the observation in the table above).