claude-code - 💡(How to fix) Fix [BUG] Stack overflow: infinite recursion between Fw (spinnerTip updater) and P5 callback in main loop [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#53175Fetched 2026-04-26 05:22:27
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
labeled ×3commented ×1

Error Message

1. Stack trace (printed on crash, repeats until stack exhausted)

  • (B:/~BUN/root/src/entrypoints/cli.js:9273:5663)
  • PI (B:/~BUN/root/src/entrypoints/cli.js:512:63749)
  • Fw (B:/~BUN/root/src/entrypoints/cli.js:512:76948)
  • P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  • Fw (B:/~BUN/root/src/entrypoints/cli.js:512:76926)
  • P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  • Fw (B:/~BUN/root/src/entrypoints/cli.js:512:77745)
  • P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  • Fw (B:/~BUN/root/src/entrypoints/cli.js:512:76926)
  • P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827) ... (Fw <-> P5 alternation continues indefinitely)

2. stderr output emitted just before the crash

Error: sandbox required but unavailable: sandbox.failIfUnavailable is set — refusing to start without a working sandbox.

3. Surrounding code context at cli.js:9273 (minified)

let j8 = hq.getSandboxUnavailableReason(); if (!j8) return; if (hq.isSandboxRequired()) { process.stderr.write( Error: sandbox required but unavailable: ${j8} + sandbox.failIfUnavailable is set — refusing to start without a working sandbox. ); ... }

  1. Additional notes
  • No .claude/logs/ entries were generated for this crash (process died before flush).
  • No exit code captured — terminal showed the stack trace then returned to the shell prompt.
  • No core dump produced.
  • The crash occurred mid-conversation; the immediately preceding user input was a normal text message (not a tool invocation, not a slash command).

Code Example

### 1. Stack trace (printed on crash, repeats until stack exhausted)                                                                   
  -  (B:/~BUN/root/src/entrypoints/cli.js:9273:5663)
  - PI (B:/~BUN/root/src/entrypoints/cli.js:512:63749)                                                                                   
  - Fw (B:/~BUN/root/src/entrypoints/cli.js:512:76948)
  - P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  - Fw (B:/~BUN/root/src/entrypoints/cli.js:512:76926)
  - P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  - Fw (B:/~BUN/root/src/entrypoints/cli.js:512:77745)
  - P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  - Fw (B:/~BUN/root/src/entrypoints/cli.js:512:76926)
  - P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  ... (Fw <-> P5 alternation continues indefinitely)

  ### 2. stderr output emitted just before the crash
  Error: sandbox required but unavailable:
    sandbox.failIfUnavailable is set — refusing to start without a working sandbox.

  ### 3. Surrounding code context at cli.js:9273 (minified)
  
  let j8 = hq.getSandboxUnavailableReason();
  if (!j8) return;
  if (hq.isSandboxRequired()) {
    process.stderr.write(`
  Error: sandbox required but unavailable: ${j8}
  `+`  sandbox.failIfUnavailable is set — refusing to start without a working sandbox.
  `);
    ...
  }

  4. Additional notes

  - No .claude/logs/ entries were generated for this crash (process died
  before flush).
  - No exit code captured — terminal showed the stack trace then returned to
  the shell prompt.
  - No core dump produced.
  - The crash occurred mid-conversation; the immediately preceding user input
  was a normal text message (not a tool invocation, not a slash command).
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

Claude Code CLI crashed with what appears to be infinite recursion / stack overflow in the main loop's spinner tip updater. The stack trace shows Fw (spinnerTip useCallback) and P5 (a useRef guard) calling each other repeatedly until the process died.

Stack trace (top frames, repeats indefinitely)

  • (B:/~BUN/root/src/entrypoints/cli.js:9273:5663)
  • PI (B:/~BUN/root/src/entrypoints/cli.js:512:63749)
  • Fw (B:/~BUN/root/src/entrypoints/cli.js:512:76948)
  • P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  • Fw (B:/~BUN/root/src/entrypoints/cli.js:512:76926)
  • P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  • Fw (B:/~BUN/root/src/entrypoints/cli.js:512:77745)
  • P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827) ... (Fw <-> P5 cycle repeats)

Side signal (printed to stderr just before the crash)

Error: sandbox required but unavailable: sandbox.failIfUnavailable is set — refusing to start without a working sandbox. This sandbox message was printed immediately before the recursion crash, but the actual termination cause is the stack overflow above, not the sandbox check.

Suspected location

Around cli.js:512:76900 — the spinnerTip useCallback (Fw) guarded by a useRef flag (P5.current). It looks like the guard is not being reset on some code path, or the setAppState setter inside the .then() re-enters synchronously and triggers another Fw call before P5.current is cleared.

Environment

  • Claude Code version: 2.1.120
  • Model: Claude Opus 4.7 (1M context) — claude-opus-4-7[1m]
  • OS: Windows 11 Pro 10.0.26200 (win32)
  • Shell: Git Bash
  • Runtime: Bun (B:/~BUN/root/...)
  • Working dir: git repo, path contains non-ASCII characters
  • Active MCP servers (many): filesystem, github, playwright, vibium, sequential-thinking, TestAI-Prod, claude_ai_Gmail, Google_Drive, Google_Calendar, notion, etc.
  • bkit plugin active (SessionStart hook injecting context)

Reproduction

Not reliably reproducible. Occurred once during a long-running session with many active plugins/MCP servers and the bkit SessionStart hook emitting a large context block. No specific user action triggered it — the crash happened mid-session.

Expected

Spinner tip update should be idempotent / debounced and never recurse into itself. Even if setAppState triggers a re-render, the P5.current guard should prevent re-entry.

Actual

Fw and P5 recurse indefinitely, exhausting the stack and killing the CLI.

What Should Happen?

The CLI should remain stable during long-running sessions. Specifically:

  1. The spinner tip updater (Fw) should be safely idempotent and protected against re-entry. The useRef guard (P5.current) must be reliably
    reset on all code paths — including when the inner setAppState call triggers a synchronous re-render or when the underlying H07(...).then() resolves/rejects unexpectedly.

  2. Even under adverse conditions (sandbox unavailable, MCP server timeouts, large hook-injected context, many concurrent plugins), the main loop should never enter unbounded recursion. A defensive depth limit or debounce on spinner tip updates would prevent stack-overflow crashes.

  3. If the sandbox is genuinely required but unavailable (sandbox.failIfUnavailable set), the CLI should exit cleanly with the stderr message that's already being printed — not crash via stack overflow afterward. The two failure modes appear entangled here.

  4. Ideally, an unhandled stack overflow in internal UI/state code should surface a clear error to the user (e.g. "internal error: spinner tip recursion — please report") rather than a raw minified stack trace, so users can recover without losing session context.

Error Messages/Logs

### 1. Stack trace (printed on crash, repeats until stack exhausted)                                                                   
  -  (B:/~BUN/root/src/entrypoints/cli.js:9273:5663)
  - PI (B:/~BUN/root/src/entrypoints/cli.js:512:63749)                                                                                   
  - Fw (B:/~BUN/root/src/entrypoints/cli.js:512:76948)
  - P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  - Fw (B:/~BUN/root/src/entrypoints/cli.js:512:76926)
  - P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  - Fw (B:/~BUN/root/src/entrypoints/cli.js:512:77745)
  - P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  - Fw (B:/~BUN/root/src/entrypoints/cli.js:512:76926)
  - P5 (B:/~BUN/root/src/entrypoints/cli.js:512:76827)
  ... (Fw <-> P5 alternation continues indefinitely)

  ### 2. stderr output emitted just before the crash
  Error: sandbox required but unavailable:
    sandbox.failIfUnavailable is set — refusing to start without a working sandbox.

  ### 3. Surrounding code context at cli.js:9273 (minified)
  
  let j8 = hq.getSandboxUnavailableReason();
  if (!j8) return;
  if (hq.isSandboxRequired()) {
    process.stderr.write(`
  Error: sandbox required but unavailable: ${j8}
  `+`  sandbox.failIfUnavailable is set — refusing to start without a working sandbox.
  `);
    ...
  }

  4. Additional notes

  - No .claude/logs/ entries were generated for this crash (process died
  before flush).
  - No exit code captured — terminal showed the stack trace then returned to
  the shell prompt.
  - No core dump produced.
  - The crash occurred mid-conversation; the immediately preceding user input
  was a normal text message (not a tool invocation, not a slash command).

Steps to Reproduce

Note: I have NOT been able to reliably reproduce this crash. It occurred
once during a long-running session. Below is the best description of the state at the time of the crash, in case it helps narrow down the trigger.

Environment at time of crash

  1. Started Claude Code in a Windows 11 (Git Bash) terminal: claude (in working dir C:\Users\win10_original\agiqa\agi-qa-workspace\tmkim, a git repo with non-ASCII characters in the parent path)

  2. Session was running with the bkit plugin active, which injects a large SessionStart hook context block (~several KB of system reminders, skill listings, deferred tool listings) on every session start.

  3. Multiple MCP servers were configured and active: filesystem, github, playwright, vibium, sequential-thinking, TestAI-Prod, claude_ai_Gmail, claude_ai_Google_Drive, claude_ai_Google_Calendar, notion, plugin_playwright_playwright.

  4. Model in use: Claude Opus 4.7 (1M context).

  5. Session had been active for an extended period with multiple turns, tool uses, and large tool results in the context window.

Last action before crash

  • Sent a normal text message to the assistant (no slash command, no tool).
  • The assistant began responding; mid-response, the CLI crashed with the stack overflow shown in "Error Messages/Logs".

What I tried for reproduction (none reproduced the crash)

  1. Restarted Claude Code in the same directory → worked normally.
  2. Opened a fresh session with the same MCP/plugin set → worked normally.
  3. Sent the same message that preceded the crash → no crash.

Hypothesized triggers (unverified)

  • Long session with many tool results may have inflated some internal state that the spinner tip updater iterates over.
  • Sandbox-unavailable condition (the stderr message printed just before the crash) may have set the system into a state where Fw/P5 lost their re-entry guard.
  • Very large SessionStart hook context (bkit) producing a render burst that re-triggered setAppState synchronously inside Fw.

If logs/replay artifacts would help, please advise what to capture next time and I'll attach them on recurrence.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

2.1.120

Claude Code Version

2.1.120

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Warp

Additional Information

ERROR FKH is not a function. (In 'FKH(K)', 'FKH' is undefined)

B:/~BUN/root/src/entrypoints/cli.js:9273:5663

9270: ${K.join( 9271: 9272)}}var oTf,mV7=1000,aTf=300,sTf=5000;var kCq=T(()=>{X8();v8();Tp();fb();uV7();q8();oN();oTf=(XmH(),Rq(WmH))});var : QV7={};P8(QV7,{useScheduledTasks:()=>eTf});function eTf({isLoading:H,assistantMode:q,setMessages:$}){let K=mD6.useRef(H);K.current=H;let _=B4(),f=Uq(),A=Gw();mD6.useEffect(()=>{if(!VG()||Iq())return;let z=(O)=>y5({value:tTf.resolveLoopDefaultFire(O),mode:"prompt",priority:"later",isMeta:!0,workload:kRH}),Y=void 0,M=vCq({onFire:z,onFireTask:(O)=>{if(O.agentId){let w=cr(O.agentId,_.getState().tasks);if(w&&!aS(w.status)){tuH(w.id,O.prompt,A);return}h([ScheduledTasks] teammate
${O.agentId} gone, removing orphaned cron ${O.id}),n8H([O.id]);return}let D=ep_(O.kind==="loop"?Claude resuming /loop
wakeup (${gV7(new Date)}):Running scheduled task (${gV7(new Date)}));$((w)=>[...w,D]),z(O.prompt)},isLoading:()=>K.cur rent,assistantMode:q,getJitterConfig:efH,isKilled:()=>!VG(),getExtraTasks:FV7&&Y?()=>FV7.getRoutineCronTasks(G9(),Y):void 0});return M.start(),()=>{M.stop()}},[q,$,_.getState,A])}function gV7(H){return H.toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"}).replace(/,? at |, /," ").replace(/ ([AP]M)/,(q,$)=>$.toLowerCase())}var mD6,tTf,FV7=null;var dV7=T(()=>{ER();X8();yq();mT();tS();zb();y78();kCq();fb();q8();g3();Dq();K9H();mD6=u(WH(),1),tTf=(XmH(),Rq(WmH))});var rV7={};P8(rV7,{REPL:()=>hCq});function cV7(H){let q=pD6.c(14),{showAllInTranscript:$,virtualScroll:K,searchBadge:_,suppressShowAll:f,status:A}=H,z=f===void 0?!1:f,Y=W1("app:toggleTranscript","Global","ctrl+o"),M=W1("transcript:toggleShowAll","Transcript","ctrl+e"),O;if(q[0]=== Symbol.for("react.memo_cache_sentinel"))O=Mc_(),q[0]=O;else O=q[0];let D=O,w=D?open in ${D}:"open in editor",j;if(q[1]===Symbol.for("react.memo_cache_sentinel"))j=f6.createElement(f6.Fragment,null,"Showing detailed transcript"),q[1]=j;else j=q[1];let P;if(q[2]!==Y)P=f6.createElement(f6.Fragment,null,Y," to toggle"),q[2]=Y,q[3]=P;else P=q[3];let W=_?"n/N to navigate":K?${_8.arrowUp}${_8.arrowDown} scroll \xB7 [ to print output \xB7 v to ${w}:z?v to
${w}:${M} to ${$?"collapse":"show all"},X;if(q[4]!==P||q[5]!==W)X=f6.createElement(v,{dimColor:!0},f6.createElement(t8 ,null,j,P,W)),q[4]=P,q[5]=W,q[6]=X;else X=q[6];let J;if(q[7]===Symbol.for("react.memo_cache_sentinel"))J=f6.createElement(p,{flexGrow:1}),q[7]=J;else J=q[7];let Z;if(q[8]!==_||q[9]!==A)Z=f6.createElement(OVf,{status:A,searchBadge:_}),q[8]=_,q[9]=A,q[10]=Z;else Z=q[10];let L;if(q[11]!==X||q[12]!==Z)L=f6.createElement(p,{noSelect:!0,alignItems:"center",alignSelf:"center",borderTopDimColor:!0,b orderBottom:!1,borderLeft:!1,borderRight:!1,borderStyle:"single",marginTop:1,paddingLeft:2,width:"100%"},X,J,Z),q[11]=X,q [12]=Z,q[13]=L;else L=q[13];return L}function OVf(H){let q=pD6.c(6),{status:$,searchBadge:K}=H;if($){let f;if(q[0]!==$)f=f6.createElement(v,null,$," "),q[0]=$,q[1]=f;else f=q[1];return f}if(K){let f;if(q[2]!==K.count||q[3]!==K.current)f=f6.createElement(v,{dimColor:!0},K.current,"/",K.count," "),q[2]=K.count,q[3]=K.current,q[4]=f;else f=q[4];return f}let _;if(q[5]===Symbol.for("react.memo_cache_sentinel"))_=f6.createElement(v,{dimColor:!0},"verbose "),q[5]=_;else _=q[5];return _}function DVf({jumpRef:H,count:q,current:$,onClose:K,onCancel:_,setHighlight:f,initialQuery:A}){let{query: z,cursorOffset:Y,handleKeyDown:M,handlePaste:O}=z0({isActive:!0,initialQuery:A,onExit:()=>K(z),onCancel:_}),[D,w]=s8.useS tate("building");s8.useEffect(()=>{let X=!0,J=H.current?.warmSearchIndex;if(!J){w(null);return}return w("building"),J().then((Z)=>{if(!X)return;if(Z<20)w(null);else w({ms:Z}),setTimeout(()=>X&&w(null),2000)}),()=>{X=!1}},[]);let j=D!=="building";s8.useEffect(()=>{if(!j)return;H.current?.setSearchQuery(z),f(z)},[z,j]);let P=Y,W=P<z.length?z[P]:" ";return f6.createElement(p,{borderTopDimColor:!0,borderBottom:!1,borderLeft:!1,borderRight:!1,borderStyle:"single",margi nTop:1,paddingLeft:2,tabIndex:0,autoFocus:!0,onKeyDown:M,onPaste:O,width:"100%",noSelect:!0},f6.createElement(v,null,"/") ,f6.createElement(v,null,z.slice(0,P)),f6.createElement(v,{inverse:!0},W),P<z.length&&f6.createElement(v,null,z.slice(P+1 )),f6.createElement(p,{flexGrow:1}),D==="building"?f6.createElement(v,{dimColor:!0},"indexing\u2026 "):D?f6.createElement(v,{dimColor:!0},"indexed in ",D.ms,"ms "):q===0&&z?f6.createElement(v,{color:"error"},"no matches "):q>0?f6.createElement(v,{dimColor:!0},$,"/",q," "):null)}function nV7(H){let q=pD6.c(6),{isAnimating:$,title:K,disabled:_,noPrefix:f}=H,A=xY(),[z,Y]=s8.useState(0),M,O;if(q[0]!==_||q[1]!==$||q[2]!== f||q[3]!==A)M=()=>{if(_||f||!$||!A)return;let w=setInterval(jVf,wVf,Y);return()=>clearInterval(w)},O=[_,f,$,A],q[0]=_,q[1]=$,q[2]=f,q[3]=A,q[4]=M,q[5]=O;else M=q[4],O=q[5];s8.useEffect(M,O);let D=$?iV7[z]??lV7:lV7;return o9H(_?null:f?K:${D} ${K}),null}function jVf(H){return H(PVf)}function PVf(H){return(H+1)%iV7.length}function hCq({commands:H,debug:q,initialTools:$,initialMessages:K,pendingHookMessages:_,initialFileHistorySnapshots:f,initialConte ntReplacements:A,initialAgentName:z,initialAgentColor:Y,mcpClients:M,dynamicMcpConfig:O,autoConnectIdeFlag:D,strictMcpCon fig:w=!1,systemPrompt:j,appendSystemPrompt:P,onBeforeQuery:W,onTurnComplete:X,disabled:J=!1,mainThreadAgentDefinition:Z,d isableSlashCommands:L=!1,remoteSessionConfig:G,directConnectConfig:V,sshSession:k,thinkingConfig:N}){let y=!!G,I=s8.useMemo(()=>yH(process.env.CLAUDE_CODE_DISABLE_TERMINAL_TITLE),[]),S=s8.useMemo(()=>!1,[]),C=s8.useMemo(()=>yH (process.env.CLAUDE_CODE_DISABLE_VIRTUAL_SCROLL),[]),B=!1;s8.useEffect(()=>{return h([REPL:mount] REPL mounted,
disabled=${J}),()=>h("[REPL:unmount] REPL unmounting")},[J]);let[x,R]=s8.useState(Z),U=w8((j8)=>j8.toolPermissionContext),F=w8((j8)=>j8.verbose),g=w8((j8)=>j8.mcp) ,Q=w8((j8)=>j8.plugins),i=w8((j8)=>j8.agentDefinitions),n=w8((j8)=>j8.initialMessage),o=Ss(),qH=w8((j8)=>j8.expandedView) ==="tasks",r=w8((j8)=>j8.pendingWorkerRequest),HH=w8((j8)=>j8.pendingSandboxRequest),t=w8((j8)=>j8.teamContext),zH=w8((j8 )=>j8.tasks),YH=w8((j8)=>j8.workerSandboxPermissions),PH=w8((j8)=>j8.elicitation),s=w8((j8)=>j8.ultraplanPendingChoice),a =w8((j8)=>j8.ultraplanLaunchPending),KH=w8((j8)=>j8.viewingAgentTaskId),e=Uq(),AH=KH?zH[KH]:void 0,_H=mP(AH)&&AH.retain&&!AH.diskLoaded;s8.useEffect(()=>{if(!KH||!_H)return;let j8=KH;k5H(S5(j8)).then((r8)=>{e((_6)=>{let H$=_6.tasks[j8];if(!mP(H$)||H$.diskLoaded||!H$.retain)return _6;let h$=H$.messages??[],MK=new Set(h$.map((lK)=>lK.uuid)),$K=r8?r8.messages.filter((lK)=>!MK.has(lK.uuid)):[];return{..._6,tas ks:{..._6.tasks,[j8]:{...H$,messages:[...$K,...h$],diskLoaded:!0}}}})})},[KH,_H,e]);let DH=B4(),MH=s8.useMemo(()=>qh(()=>DH.getState(),e),[DH,e]),XH=s8.useMemo(()=>l0H(()=>DH.getState(),e),[DH,e]),jH=vi(),GH=V w(),[vH,LH]=s8.useState(H);aL7(y?void 0:G9(),LH);let VH=w8((j8)=>j8.isBriefOnly),IH=s8.useMemo(()=>tG(U),[U,VH]);hj_(),yj _();let[BH,sH]=s8.useState(O),dH=s8.useCallback((j8)=>{sH(j8)},[sH]),[z8,M8]=s8.useState("prompt"),[TH,CH]=s8.useState(!1 ),[mH,xH]=s8.useState(!1),[aH,rH]=s8.useState(""),nH=s8.useRef(0),cH=s8.useRef(void 0),tH=s8.useRef(!1),{addNotification:V8,removeNotification:B8}=f_(),H6=AVf,d8=nL7(M,g.clients),[iH,x8]=s8.useState(void 0),[UH,f8]=s8.useState(null),[kH,oH]=s8.useState(null),[O8,L8]=s8.useState(!1),[fH,wH]=s8.useState(()=>{return!1}),uH=w8( (j8)=>j8.showRemoteCallout),[bH,eH]=s8.useState(()=>sG7());uT7(),pT7(),CT7({ideSelection:iH,mcpClients:d8,ideInstallation Status:kH}),k07({mcpClients:d8}),E07(),$T7(),fT7(),Mf6(),XT7(GH),rT7(),sT7(),ZT7(GH),TT7(),ST7(),NT7(),_Vf(),SG7(),FG7(), lG7(),S07(),QT7();let{recommendation:RH,handleResponse:T8}=d07(),{recommendation:D8,handleResponse:c8}=o07(),{pending:U8, handleAction:l6,skipForSession:h6}=KVf(),Fq=s8.useMemo(()=>{return[...IH,...$]},[IH,$]);oO6({enabled:!y}),$Z7({enabled:!y });let Aq=$M_();s8.useEffect(()=>{if(y)return;OT7(e)},[e,y]),s8.useEffect(()=>{let j8=setTimeout(vV7,500);return()=>clear Timeout(j8)},[]),rG7(y?ECq:d8,U.mode),s8.useEffect(()=>{_hq(U.mode)},[U.mode]),qL7(e,K,{enabled:!y});let O$=m56(Fq,g.tools,U),{tools:fK,allowedAgentTypes:F6}=s8.useMemo(()=>{if(!x)return{tools:O$,allowedAgentTypes:void 0};let j8=Gd(x,O$,!1,!0);return{tools:j8.resolvedTools,allowedAgentTypes:j8.allowedAgentTypes}},[x,O$]),Pq=s8.useRef(fK);Pq.curr ent=fK;let SK=s8.useMemo(()=>{if(!wP())return fK;let j8=new Set(fK.map((_6)=>_6.name)),r8=izH().filter((_6)=>!j8.has(_6.name));return r8.length>0?[...fK,...r8]:fK},[fK]),pK=CIq(vH,Q .commands),I7=CIq(pK,g.commands),gq=s8.useMemo(()=>L?[]:I7,[L,I7]);qw7(y?ECq:g.clients),zZ7(y?ECq:g.clients,x8);let[D4,w4 ]=s8.useState([]),[p1,l9]=s8.useState(null);s8.useEffect(()=>{if(p1&&!p1.isStreaming&&p1.streamingEndedAt){let r8=30000-(Date.now()-p1.streamingEndedAt);if(r8>0){let _6=setTimeout(l9,r8,null);return()=>clearTimeout(_6)}else l9(null)}},[p1]);let[z7,pA]=s8.useState(null),B1=s8.useRef(null);B1.current=z7;let CD=s8.useRef(null),pw=s8.useRef(()=>{} ),_9=s8.useRef(()=>{}),N3=s8.useRef(null),qW=s8.useRef(null),Bw=s8.useRef(0),jA=s8.useRef(new zSq).current,zz=s8.useSyncE xternalStore(jA.subscribe,jA.getSnapshot),[ff,S9]=s8.useState(G?.hasInitialPrompt??!1),B_=zz||ff,[PA,$1]=s8.useState(void 0),Nf=s8.useRef(0),K1=s8.useRef(!1),WA=s8.useRef(0),Af=s8.useRef(0),sY=s8.useRef(null),lO=s8.useCallback(()=>{WA.current =Date.now(),Af.current=0,sY.current=null},[]),Fj=s8.useRef(!1);if(zz&&!Fj.current)lO();Fj.current=zz;let FM=s8.useCallback((j8)=>{if(S9(j8),j8)lO()},[lO]),tY=s8.useRef(null),bD=s8.useRef(void 0),zY=s8.useRef(void 0),$W=1500,[X A,D5]=s8.useState(!1);s8.useEffect(()=>{if(o$())r3K().then((j8)=>{if(j8)V8({key:"tmux-mouse-hint",text:j8,priority:"low"} )});o3K().then((j8)=>{if(j8)V8({key:"tmux-focus-hint",text:j8,priority:"low"})})},[]);let[nO,gj]=s8.useState(!1);s8.useEf fect(()=>{},[]);let[J6,P$]=s8.useState(null),LK=s8.useRef(null),oK=s8.useCallback((j8)=>{if(j8?.isLocalJSXCommand){let{cl earLocalJSX:r8,..._6}=j8;LK.current={..._6,isLocalJSXCommand:!0},P$(_6);return}if(LK.current){if(j8?.clearLocalJSX){LK.cu rrent=null,P$(null);return}return}if(j8?.clearLocalJSX){P$(null);return}P$(j8)},[]),[aK,f9]=s8.useState(()=>new Map),a1=s8.useCallback((j8)=>{f9((r8)=>mZ7(r8,j8))},[]),[E7,Q$]=s8.useState([]),ZK=s8.useMemo(()=>GD7(Q$),[Q$]),[b4,_4]=s 8.useState(null),[cK,BA]=s8.useState([]),[n4,EY]=s8.useState([]),Uw=s8.useRef(new Map),Qj=w8((j8)=>j8.settings.terminalTitleFromRename)!==!1,rf=s8.useSyncExternalStore($hq,()=>Qj?XD(E8()):void 0);s8.useEffect(()=>{return Hhq(()=>{let j8=GcH();if(!j8)return;e((r8)=>{if(r8.standaloneAgentContext?.name===j8)return r8;return{...r8,standaloneAgentContext:{...r8.standaloneAgentContext,name:j8}}})})},[e]);let[z_,dj]=s8.useState(),xD=s8.u seRef((K?.length??0)>0),_L=x?.agentType,_1=rf??_L??z_??"Claude Code",of=E7.length>0||n4.length>0||r||HH,Ef=J6?.isLocalJSX Command===!0&&J6?.jsx!=null,uD=s8.useMemo(()=>u76(zH),[zH]),KW=of||Ef?"waiting":B_||uD?"busy":"idle",gM=s8.useMemo(()=>jz 7(zH),[zH]),_W=KW==="idle"&&gM?"busy":KW,JA=KW==="busy";s8.useEffect(()=>{if(KW==="busy")return _D7(),()=>fD7()},[KW]);let w5=KW!=="waiting"?void 0:E7.length>0?approve ${E7[0].tool.name}:r?"worker request":HH?"sandbox request":Ef?"dialog open":"input needed";s8.useEffect(()=>{CI8({status:_W,waitingFor:w5})},[_W,w5]);let QM=$77(zH),kK=jc8();s8.useEffect(()=>{oy_({tasks:Q M.count,queued:kK,kinds:QM.kinds})},[QM.count,kK,QM.kinds.join(",")]);let E3=S8("tengu_terminal_sidebar",!1)&&(y8().showS tatusInTerminalTab??!1),ex=w8((j8)=>j8.postTurnSummary?.status_detail);Ng8(I||!E3?null:KW,ex),s8.useEffect(()=>{return bTK(ZK),()=>xTK()},[ZK]);let[R4,ih]=s8.useState(K??[]),zf=s8.useRef(R4),N0=s8.useRef(!1),U_=s8.useCallback((j8)=>{let r8=zf.current,_6=typeof j8==="function"?j8(zf.current):j8;if(zf.current=_6,_6.length<Nf.current)Nf.current=0,K1.current=!1,$1(void 0);else if(_6.length>r8.length&&K1.current){let H$=_6.length-r8.length;if((r8.length===0||_6[0]===r8[0]?_6.slice(-H$):_6.slice(0,H$)).some(A98))K1.current=!1;else Nf.current=_6.length}ih(_6)},[]),U5=s8.useCallback((j8)=>U_((r8)=>lO6(r8,j8)),[U_]);BG7(s8.useCallback((j8)=>U_((r8)=>[.. .r8,$6({content:LA6(j8),isMeta:!0})]),[U_]));let kX=s8.useCallback((j8)=>{if(j8!==void 0)Nf.current=zf.current.length,K1.current=!0;else K1.current=!1;$1(j8)},[]),{dividerIndex:NX,dividerYRef:fL,onScrollAway:CV,onRepin:KN,jumpToNew:Fs,shiftDivider:iO}=fe_(R4 .length);xG7(R4,U_,B_,Bw,!y);let[E0,FH]=s8.useState(null),lH=s8.useRef(E0);lH.current=E0;let o8=s8.useRef(null),H8=s8.useMemo(()=>Ae_(R4,NX),[NX,R4.length]),F8=s8.useCallback((j8=!1,r8="?")=>{if(!j8&&!xf("autoScrol lEnabled",!0).value)return;let _6=N3.current;if(_6&&!_6.isSticky())h(repinScroll(${r8}, force=${j8}): yanking from scrollTop=${_6.getScrollTop()} (max=${Math.max(0,_6.getScrollHeight()-_6.getViewportHeight())}));if(_6?.scrollToBottom() ,KN(),lH.current!==null)FH(null)},[KN]),y6=R4.at(-1),G6=y6!=null&&A98(y6);s8.useEffect(()=>{if(G6)F8(!1,"lastMsgIsHuman") },[G6,y6,F8]);let{maybeLoadOlder:bq}=YVf,sq=s8.useCallback((j8,r8)=>{if(Bw.current=Date.now(),j8)KN();else CV(r8)},[KN,CV,bq]),k_=UJ7(_,U_),[Yf,U1]=s8.useState(null);s8.useState(()=>{return H$6(pr6()),null});let O_=s8.useRef(eq6()),i4=GP_(),n_=s8.useCallback(()=>D5(!1),[]),v4=Ei(n_,$W),Uz=s8.useRef(null),Z9=s8.useCallback((j8)=>{if (H6(O_.current,j8))return;if(O_.current===""&&j8!==""&&Date.now()-Bw.current>=MVf)F8(!1,"typedIntoEmpty");O_.current=j8,H $6(j8),wqH.recordUserActivity(),TOH(!0);let r8=j8.trim().length>0;if(D5(r8),r8)v4();else v4.cancel()},[D5,F8,H6,v4]),[Yz,rO]=s8.useState("prompt"),[fW,rh]=s8.useState(),mD=s8.useCallback((j8)=>{let r8=new Set(j8.slash_commands);LH((_6)=>_6.filter((H$)=>r8.has(H$.name)||pEq.has(H$))),e((_6)=>_6.mainLoopModel===j8.model?_6:{.. ._6,mainLoopModel:j8.model})},[LH,e]),[h0,_N]=s8.useState(new Set),wI=s8.useCallback((j8)=>{_N((r8)=>{switch(j8.action){case"add":{let _6=new Set(r8);for(let H$ of j8.ids)_6.add(H$);return _6}case"remove":{let _6=new Set(r8);for(let H$ of j8.ids)_6.delete(H$);return _6.size===r8.size?r8:_6}case"clear":return r8.size>0?new Set:r8}})},[]),EX=s8.useRef(!1),y0=s8.useRef(0),oh=s8.useRef([]) ,yU=s8.useRef(0),uc=s8.useCallback((j8)=>{y0.current+=j8;let r8=oh.current;if(j8>0&&r8.length>0){let _6=r8.at(-1);if(_6.outputTokens==null)_6.lastTokenTime=Date.now(),_6.endResponseLength=y0.current}},[]),JVH=s8.useCallbac k(()=>{y0.current=0},[]),uKH=s8.useCallback((j8)=>{if(j8.type==="start"){let r8=Date.now(),_6=y0.current;oh.current.push( {id:j8.id,ttftMs:j8.ttftMs,firstTokenTime:r8,lastTokenTime:r8,responseLengthBaseline:_6,endResponseLength:_6})}else{let r8=j8.id!=null?oh.current.find((_6)=>_6.id===j8.id):oh.current.findLast((_6)=>_6.id==null);if(r8){if(r8.outputTokens=j8.o utputTokens,r8.lastTokenTime=Date.now(),j8.id==null)y0.current=Math.max(y0.current,r8.responseLengthBaseline+j8.outputTok ens*4)}}},[]),SU=fJ7({config:G,setMessages:U_,setIsLoading:FM,onInit:mD,setToolUseConfirmQueue:ZK,tools:Fq,setStreamingTo olUses:w4,setStreamMode:Pz8,setInProgressToolUseIDs:wI,recordApiMetricsEvent:uKH,permissionMode:U.mode}),gs=MJ7({config:V ,setMessages:U_,setIsLoading:FM,setToolUseConfirmQueue:ZK,tools:Fq,permissionMode:U.mode}),RU=wJ7({session:k,setMessages: U_,setIsLoading:FM,setToolUseConfirmQueue:ZK,tools:Fq,permissionMode:U.mode}),AW=s8.useMemo(()=>RU.isRemoteMode?e16("ssh" ,RU,!1):gs.isRemoteMode?e16("direct",gs,!1):SU.isRemoteMode?e16("ccr",SU,G?.viewerOnly??!1,G?.sessionId):aLq,[RU,gs,SU,G? .viewerOnly,G?.sessionId]);s8.useEffect(()=>{let j8=AW.isRemoteMode?AW:null,r8=AW.isRemoteMode&&AW.kind==="ccr"?"ccr-api" :"local-jsonl",_6=COH();if(_6.remote!==j8||_6.transcriptSource!==r8)HW6({..._6,remote:j8,transcriptSource:r8})},[AW]);let [UA,O2]=s8.useState({}),[jI,mKH]=s8.useState(0),[PI,bV]=s8.useState(null),mc=!(w8((j8)=>j8.settings.prefersReducedMotion) ??!1)&&!FjK(),WI=s8.useCallback((j8)=>{if(!mc)return;bV(j8)},[mc]),VZ=PI&&mc?PI.substring(0,PI.lastIndexOf(

9273 )+1)||null:null,[xV,Qs]=s8.useState(0),[ds,Hu]=s8.useState(!1),[QMH,cs]=s8.useState(void : 0),[ls,pKH]=s8.useState(!1),[dMH,fN]=s8.useState(bMH.randomUUID()),[IU,vZ]=s8.useState(null),pc=s8.useCallback((j8)=>{let r8=eO7(j8,VP);if(r8)vZ(r8)},[]),BKH=s8.useRef(xV);BKH.current=xV;let[ns]=s8.useState(()=>({current:IhK(K,A)})),[CU]=s8.u seState(()=>({current:oQK(K??[])})),[Bc,zW]=s8.useState(y8().hasAcknowledgedCostThreshold),[Uc,D2]=s8.useState(!1),[h8,i6 ]=s8.useState(!1),X$=s8.useRef("INSERT");s8.useEffect(()=>{if(s&&Uc)D2(!1)},[s,Uc]);let j4=xY(),f4=s8.useRef(j4);f4.curre nt=j4;let[f1]=wK(),P5=s8.useRef(!1),Fw=s8.useCallback(()=>{if(P5.current)return;P5.current=!0;let j8=zf.current.slice(gc.current);for(let r8 of d9q(j8))QKH.current.add(r8);gc.current=zf.current.length,H07({theme:f1,read FileState:bU.current,bashTools:QKH.current}).then(async(r8)=>{if(r8){let _6=await r8.content({theme:f1});e((H$)=>({...H$,spinnerTip:_6})),q07(r8)}else e((_6)=>{if(_6.spinnerTip===void 0)return _6;return{..._6,spinnerTip:void 0}})})},[e,f1]),LA=s8.useCallback(()=>{FM(!1),kX(void 0),y0.current=0,oh.current=[],yU.current++,bV(null),w4([]),p3q(),Pz8("responding"),Fw(),rr(),go8()},[Fw]),w2=s8.useMemo(( )=>XJH(zH).some((j8)=>j8.status==="running"),[zH]);s8.useEffect(()=>{if(!w2&&tY.current!==null){let j8=Date.now()-tY.current,r8=bD.current;tY.current=null,bD.current=void 0,U_((_6)=>[..._6,bLq(j8,r8,$q(_6,HKH))])}},[w2,U_]);let AL=s8.useRef(!1);s8.useEffect(()=>{{if(U.mode!=="auto"){AL.curre nt=!1;return}if(AL.current)return;if((y8().autoPermissionsNotificationCount??0)>=3)return;let _6=setTimeout((H$,h$)=>{H$.current=!0,a8((MK)=>{let $K=MK.autoPermissionsNotificationCount??0;if($K>=3)return MK;return{...MK,autoPermissionsNotificationCount:$K+1}}),h$((MK)=>[...MK,f5(_O6,"warning")])},800,AL,U_);return()=>clearT imeout(_6)}},[U.mode,U_]);let ClH=s8.useRef(!1),cMH=s8.useRef(!1);s8.useEffect(()=>{if(cMH.current)return;let j8=q5();if(!j8?.creationDurationMs||j8.usedSparsePaths)return;if(j8.creationDurationMs<15000)return;cMH.current=!0;let r8=Math.round(j8.creationDurationMs/1000);U_((_6)=>[..._6,f5(Worktree creation took ${r8}s. For large repos, set `worktree.sparsePaths` in .claude/settings.json to check out only the directories you need \u2014 e.g. `{"worktree": {"sparsePaths": ["src", "packages/foo"]}}`.,"info")])},[U_]);let{onBeforeQuery:UKH,onTurnComplete:LVH,onSessionRestored :FKH,render:iW8,ownsInput:ZVH}=XJ7({enabled:S,setMessages:U_,setInputValue:Z9,setToolJSX:oK,resultDedupState:CU.current}) ,lMH=(!J6||J6.showSpinner===!0)&&E7.length===0&&n4.length===0&&(B_||PA||w2||jc8()>0)&&!r&&(!VZ||VH),is=E7.length>0||n4.le ngth>0||cK.length>0||PH.queue.length>0||YH.queue.length>0;DD7({sandboxHost:cK[0]?.hostPattern.host,promptTitle:n4[0]?.tit le,elicitationServer:PH.queue[0]?.serverName,workerSandboxHost:YH.queue[0]?.host});let nMH=qG7({hasActivePrompt:is,otherS urveyActive:!1}),gKH=_G7(R4,B_,is,{enabled:!y}),S0=eZ7(R4,B_,is,{enabled:!y,otherSurveyActive:nMH.state!=="closed"||gKH.s tate!=="closed"}),GVH=nZ7(R4,B_,jI,"session",is,nMH.state!=="closed"||gKH.state!=="closed"||S0.state!=="closed"),uV=OV7(R 4,jI),blH=s8.useMemo(()=>({...GVH,handleSelect:(j8)=>{if(kVH.current=!1,GVH.handleSelect(j8),j8==="bad"&&qV7("feedback_su rvey_bad"))dKH("feedback_survey_bad"),kVH.current=!0}}),[GVH]),rW8=$Vf(R4,B_,is,nMH.state!=="closed"||blH.state!=="closed "||gKH.state!=="closed"||S0.state!=="closed");RZ7({autoConnectIdeFlag:D,ideToInstallExtension:UH,setDynamicMcpConfig:sH,s etShowIdeOnboarding:L8,setIDEInstallationState:oH}),X07(f,(j8)=>e((r8)=>({...r8,fileHistory:j8})));let oW8=s8.useCallback(async(j8,r8,_6)=>{let H$=performance.now();try{let h$=hz8(r8.messages),MK=mO8();await q0H("resume",{getAppState:()=>DH.getState(),setAppState:e,signal:AbortSignal.timeout(MK)});let{agentDefinition:$K}=HVH(r8 .agentSetting,Z,i);R($K),e((F1)=>({...F1,agent:$K?.agentType}));let lK=await yb("resume",{sessionId:j8,agentType:$K?.agentType,model:GH});if(h$.push(...lK),_6==="fork")aBK(r8,JJ(j8));else Hr8(r8,JJ(j8));if(r8.fileHistorySnapshots)o66(r8);if(e((F1)=>({...F1,standaloneAgentContext:AW8(r8.agentName,r8.agentColo r)})),Xv(r8.agentName),sW8(h$,r8.projectPath??Kq()),_6!=="fork")oMH.current.current=I38(h$,Fq);LA(),pA(null),fN(j8);let q$=f7q(j8);r18(),EvH(),x0(JJ(j8),r8.fullPath?BD6.dirname(r8.fullPath):null);let{renameRecordingForSession:Y_}=await Promise.resolve().then(() => (_W8(),WZ7));if(await Y_(),await aB(),fW8(r8,e),uO8(),Zs(r8),xD.current=!0,dj(void 0),_6!=="fork")JZ7(r8.worktreeSession===void 0?r8.projectPath:r8.worktreeSession?.worktreePath),zW8(r8.worktreeSession,r8.projectPath),Ls(),GMq({abortController:new AbortController,taskRegistry:MH}),$l(DN().map((F1)=>F1.id)),BIq(h$);else{let F1=q5();if(F1)BR(F1)}if(q$)mnH(q$);if(ns.cur rent&&_6!=="fork")ns.current=Il8(h$,r8.contentReplacements??[]);if(U_(()=>h$),oK(null),Z9(""),_6!=="fork")pc(h$);d("tengu _session_resumed",{entrypoint:_6,success:!0,resume_duration_ms:Math.round(performance.now()-H$)})}catch(h$){throw d("tengu_session_resumed",{entrypoint:_6,success:!1,failure_reason:"processing_error",error_name:n6(h$).name}),h$}},[LA,e ,MH,pc]),[Fc]=s8.useState(()=>Db(Np)),bU=s8.useRef(Fc),QKH=s8.useRef(new Set),gc=s8.useRef(0),xlH=s8.useRef(new Set),ulH=s8.useRef(new Map),TVH=s8.useRef(new Set),iMH=s8.useRef(new Map),VVH=s8.useRef(void 0),rMH=s8.useRef(AAH()),aW8=s8.useRef(Df8()),oMH=s8.useRef(iFH()),sW8=s8.useCallback((j8,r8)=>{let _6=qpH(j8,r8,Np);bU.current=tbH(bU.current,_6);for(let H$ of d9q(j8))QKH.current.add(H$)},[e]);s8.useEffect(()=>{if(K&&K.length>0)sW8(K,Kq()),GMq({abortController:new AbortController ,taskRegistry:MH}),BIq(K),pc(K),oMH.current.current=I38(K,Fq),FKH(K)},[]);let{status:tW8,reverify:vVH}=gJ7(),[qu,dKH]=s8. useState(null),kVH=s8.useRef(!1),[mlH,plH]=s8.useState(null),[BlH,UlH]=s8.useState(!1),FlH=!B_&&ls;function aMH(){if(BlH||mlH)return;if(ds)return"message-selector";if(XA)return;if(cK[0])return"sandbox-permission";let j8=!J6||J6.shouldContinueAnimation;if(j8&&E7[0])return"tool-permission";if(j8&&n4[0])return"prompt";if(j8&&YH.queue[0])re turn"worker-sandbox-permission";if(j8&&PH.queue[0])return"elicitation";if(j8&&FlH)return"cost";if(j8&&IU)return"resume-re turn";if(j8&&!B_&&s)return"ultraplan-choice";if(j8&&!B_&&a)return"ultraplan-launch";if(k7()){if(j8&&uH)return"remote-call out";return}if(j8&&O8)return"ide-onboarding";if(j8&&uH)return"remote-callout";if(j8&&RH)return"lsp-recommendation";if(j8& &D8)return"plugin-hint";if(j8&&bH)return"desktop-upsell";return}let W5=aMH(),eW8=XA&&(cK[0]||E7[0]||n4[0]||YH.queue[0]||PH.queue[0]||FlH);zY.current=W5,s8.useEffect(()=>{if(!B_)return;let j8=W5==="tool-permission",r8=Date.now();if(j8&&sY.current===null)sY.current=r8;else if(!j8&&sY.current!==null)Af.current+=r8-sY.current,sY.current=null},[W5,B_]);let glH=s8.useRef(W5),FA=s8.useRef(null);s8.useLayoutEffect(()=>{let j8=glH.current==="tool-permission",r8=W5==="tool-permission";if(glH.current=W5,j8===r8)return;let _6=N3.current;if(r8)FA.current=_6&&!_6.isSticky()?_6.getScrollTop():null,F8(!0,"permissionDialogAppear");else if(FA.current!==null)_6?.scrollTo(FA.current),FA.current=null;else F8(!0,"permissionDialogDismiss")},[W5,F8]);let rs=J6?.jsx!=null,H28=s8.useRef(rs);s8.useLayoutEffect(()=>{if(H28.current!==rs&&(N3.current?.isSticky()??!0))F8(!1,toolJ sxDialog\u2192${rs});H28.current=rs},[rs,F8]);function NVH(){if(W5==="elicitation")return;if(h([onCancel] focusedInputDialog=${W5} streamMode=${Xd.getState().mode}`),jA.forceEnd(),PI?.trim())U_((j8)=>[...j8,Zw({content:PI})]);i f(LA(),W5==="tool-permission")E7[0]?.onAbort(),ZK([]);else if(W5==="prompt"){for(let j8 of n4)j8.reject(Error("Prompt cancelled by user"));EY([]),z7?.abort("user-cancel")}else if(AW.isRemoteMode)AW.cancelRequest();else z7?.abort("user-cancel");pA(null),LVH(zf.current,!0)}let q28=s8.useCallback(()=>{let j8=Wc8(O_.current,0);if(!j8)return;if(Z9(j8.text),rO("prompt"),j8.images.length>0)O2((r8)=>{let _6={...r8};for(let H$ of j8.images)6[H$.id]=H$;return 6})},[Z9,rO,O2]),$28={setToolUseConfirmQueue:ZK,onCancel:NVH,getConnectionSummary:()=>CD.c urrent?.summary(),onAgentsKilled:()=>U((j8)=>[...j8,qB()]),isMessageSelectorVisible:ds||!!Uc,screen:z8,abortSignal:z7?. signal,isExternalLoading:ff,popCommandFromQueue:q28,isLocalJSXCommand:J6?.isLocalJSXCommand,isInputOverlayActive:h8,input Mode:Yz,isInputEmpty:i4};s8.useEffect(()=>{if(y)return;if(W2()>=5&&!ls&&!Bc){if(d("tengu_cost_threshold_reached",{}),zW(! 0),$R8())pKH(!0)}},[R4,ls,Bc]);let Vw6=s8.useCallback(async(j8)=>{let r8=DH.getState(),{mode:_6,isBypassPermissionsModeAv ailable:H$}=r8.toolPermissionContext;switch(wv8(_6,H$)){case"allow":return!0;case"deny":return!1;case"classify":return Nq6(j8.host,j8.port,zf.current,Pq.current,r8.toolPermissionContext,new AbortController().signal);case"ask":break}if(EK()&&y98()){let MK=KQK(),$K=await _QK(j8.host,MK);return new Promise((lK)=>{if(!$K){BA((q$)=>[...q$,{hostPattern:j8,resolvePromise:lK}]);return}YQK({requestId:MK,host:j8.host,resolve :lK}),e((q$)=>({...q$,pendingSandboxRequest:{requestId:MK,host:j8.host}}))})}return new Promise((MK)=>{let $K=!1;function lK(q$){if($K)return;$K=!0,MK(q$)}BA((q$)=>[...q$,{hostPattern:j8,resolvePromise:lK}]);{let

extent analysis

TL;DR

The most likely fix for the infinite recursion issue in the Claude Code CLI is to ensure the P5.current guard is properly reset on all code paths to prevent re-entry into the Fw function.

Guidance

  1. Review the P5.current guard: Verify that the P5.current guard is being reset correctly in all possible code paths, including when the inner setAppState call triggers a synchronous re-render or when the underlying H07(...).then() resolves/rejects unexpectedly.
  2. Check for missing returns: Ensure that all functions, especially those involved in the recursion, have proper return statements to prevent unintended re-entries.
  3. Debounce spinner tip updates: Consider implementing a debounce mechanism for spinner tip updates to prevent rapid successive calls that could lead to recursion.
  4. Error handling: Improve error handling to catch and handle potential errors that might cause the recursion, such as sandbox unavailability, to prevent the application from crashing.

Example

No specific code example can be provided without modifying the existing codebase, but ensuring that P5.current is reset after each use, like so, could help prevent recursion:

if (P5.current) {
  // Perform action
  P5.current = false; // Reset the guard
}

Notes

  • The provided code snippet is minified and complex, making it difficult to pinpoint the exact cause without further debugging.
  • The issue seems related to the interaction between Fw and P5 functions and their guards, but the root cause might be deeper in the codebase.

Recommendation

Apply a workaround by adding a debounce to the spinner tip update function to prevent rapid successive calls, which could help mitigate the recursion issue until a more permanent fix can be implemented.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] Stack overflow: infinite recursion between Fw (spinnerTip updater) and P5 callback in main loop [1 comments, 2 participants]