Skip to content

Messages sent while /compact runs are rejected and cannot be queued #10724

Description

@KelvinChung2000

What happened

I can no longer queue a message while a context compaction is running against the
Claude backend. Sending during /compact does not hold the message until the
compaction finishes; the send is refused and I have to wait and retype or resend.

Diagnosis

ProviderCommandReactor refuses any turn start on a thread whose id is in the
in-flight compaction set:

apps/server/src/orchestration/Layers/ProviderCommandReactor.ts:1419
  if (compactingThreadIds.has(event.payload.threadId)) {
    return yield* appendTurnStartFailure(
      "Provider turn start failed",
      "Wait for context compaction to finish before sending another message.",
    );
  }

The thread id is added at line 1393 when a compact command is accepted and removed
in the Effect.ensuring at line 1414, so the whole compaction window rejects sends.
The client clears its in-flight send when that provider.turn.start.failed activity
arrives (apps/web/src/components/ChatView.logic.ts:990-994); per #9620's
description it also removes the optimistic message and restores the draft, which is
what "cannot queue" looks like from the composer.

This is not the Claude SDK's own auto-compaction. On auto-compaction ClaudeAdapter
maps status: "compacting" to session state waiting
(apps/server/src/provider/Layers/ClaudeAdapter.ts:3411), which
orchestrationSessionStatusFromRuntimeState maps to running
(ProviderRuntimeIngestion.ts:267-269), so the session stays busy and this guard is
not reached. Whether the SDK accepts a steer mid auto-compaction was not exercised
here.

The guard shipped with #9293 (merged 2026-09-04), which added the /compact
command. #9620, opened the same day to queue these sends, was closed unmerged.
#10096, the current fix, has been open since 2026-09-05 and is not merged, and
main still carries the Set-based guard, so neither v0.0.40 nor the
v0.0.41 nightlies contain a fix.

Compaction on this machine took 1m52s and 1m38s in the two recorded cases, so the
window in which sends are refused is minutes long, not seconds.

Steps to reproduce

  1. Open a Claude thread with enough history that compaction is worth running.
  2. Send /compact.
  3. While Compacting… is showing, type a message and press enter.
  4. The message is not queued. A "Provider turn start failed" activity appears with
    detail "Wait for context compaction to finish before sending another message.",
    the optimistic message is removed and the draft is restored.

Version

0.0.40

Environment

Linux x64 (kernel 7.1.1), Node v24.10.0, desktop app against the local server,
claude provider (claude-fable-5-1), launched via bunx t3. Only the desktop
surface was exercised; the guard is in the orchestration reactor, so the website
and mobile should behave the same way.

Evidence

projection_thread_activities, thread 0b11dcb0:

2026-09-07T13:10:18.191Z  user message   /compact
2026-09-07T13:10:30.976Z  user message   (follow-up)
2026-09-07T13:10:30.976Z  provider.turn.start.failed
    {"detail":"Wait for context compaction to finish before sending another message.",
     "requestId":"00488345-9e79-4fa4-afe1-8b905b187cbd"}
2026-09-07T13:12:10.378Z  context-compaction  Compacted context 340K -> 11.7K tokens

2026-09-08T10:47:37.486Z  user message   /compact
2026-09-08T10:48:07.504Z  user message   (follow-up)
2026-09-08T10:48:07.504Z  provider.turn.start.failed
    {"detail":"Wait for context compaction to finish before sending another message.",
     "requestId":"23e67880-935e-42ef-bd99-d75f0ab61cd7"}
2026-09-08T10:49:15.746Z  context-compaction  Compacted context 153K -> 9.96K tokens
2026-09-08T10:51:49.039Z  user message   (same follow-up, resent by hand)

Related issues

No open issue covers this. #10096 is the unmerged fix; #9620 was the earlier
attempt, closed unmerged; #9293 introduced the guard. #7589 is a different
post-/compact defect (thread stuck on Working).

Fix applied or workaround

Nothing was changed on the machine. Workaround: wait for the compaction divider
before sending; the draft is restored so the text is not lost, but it has to be
resent by hand.

Filed by

claude (opus-5) via t3 triage

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions