[Bug] Prompt suggestions never displayed — timing race condition clears suggestion before response completes
Bug Description
Bug Report: Prompt suggestions never appear due to timing race condition
Description
Prompt suggestions never appear despite being enabled via both settings (promptSuggestionEnabled) and environment variable (CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=1). This has been the case for months across multiple versions, currently on v2.1.34.
Root Cause Analysis
After tracing the source code in cli.js, I identified a timing race condition in the prompt suggestion lifecycle:
- Xt4() (suggestion generator) is called as fire-and-forget (no await) inside _t4() — it runs in parallel with the main response stream.
- Xt4() makes a separate, lighter API call (ICA() → Lv()) that almost always completes before the main response finishes streaming.
- When the suggestion arrives, it sets appState.promptSuggestion.text via setAppState, triggering a component re-render.
- During this re-render, isAssistantResponding is still true (main response is still streaming), so the aDq hook returns null for the filtered suggestion (sw):
// In aDq hook:
_ = isAssistantResponding || inputValue.length > 0 ? null : suggestionText;
- The timing check in the component body then fires:
if (e1.text && !sw && e1.shownAt === 0)
JI("timing", e1.text), / clears promptSuggestion to null /
- This permanently deletes the suggestion because e1.text exists (raw state), sw is null (filtered), and shownAt === 0 (never displayed).
- When the main response finishes and isAssistantResponding becomes false, e1.text is already null — there is nothing left to display.
Additional Factor
CCA() (the speculation mode gate) is hardcoded to return false:
function CCA() { return h("[Speculation] enabled=false"), !1; }
If speculation were enabled, SCA() would immediately consume the suggestion upon arrival, bypassing the timing issue. But with speculation disabled, the only display path is through the placeholder prop — which is killed by the timing check.
Expected Behavior
Prompt suggestions should appear as ghost text in the input field after the assistant finishes responding.
Actual Behavior
Suggestions are generated successfully but immediately discarded by the "timing" race condition before they can ever be displayed.
Reproduction
- Set CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION=1
- Start a conversation with 2+ turns
- Wait for assistant response to complete
- Observe: no suggestion appears in the input field (it was generated and deleted during the response)
Environment
- Claude Code v2.1.34 (binary install via curl)
- macOS (Darwin 25.1.0, arm64)
- Sonnet 4.5
Suggested Fix
The timing check should either:
- Defer evaluation until isAssistantResponding becomes false (e.g., move to a useEffect with dependency on isAssistantResponding)
- Not clear suggestions that arrive during response streaming — instead, hold them until the response completes
Environment Info
- Platform: darwin
- Terminal: iTerm.app
- Version: 2.1.34
- Feedback ID: 25f37729-4f40-4f61-b40e-eb37dc4b2a5b
Errors
[{"error":"Error\n at _k (/$bunfs/root/claude:28:1144)\n at <anonymous> (/$bunfs/root/claude:33:10063)\n at emit (node:events:92:22)\n at endReadableNT (internal:streams/readable:861:50)\n at processTicksAndRejections (native:7:39)\n at request (/$bunfs/root/claude:35:2149)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-02-07T03:10:06.415Z"}]This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗