Skip to content

TUI crashes with uncaught React error #185 (Maximum update depth exceeded) a few seconds after a background task is registered #11783

Description

@Disk-MTH

What happened?

Summary

The interactive TUI process dies with an uncaught Minified React error #185
a few seconds after the agent registers a background shell task
(run_shell_command with is_background: true). React 19.2.0 error catalog:
"Maximum update depth exceeded. This can happen when a component repeatedly
calls setState inside componentWillUpdate or componentDidUpdate. React limits
the number of nested updates to prevent infinite loops."

The crash is not deterministic: in one session, 2 of 4 background-task
registrations crashed the TUI 2-4 s after the launch; a 5th long-running
command run in the foreground (no background registration) did not crash.

Steps to reproduce

  1. Start an interactive TUI session in any project.
  2. Have the agent run a long command in the background, e.g.
    run_shell_command with is_background: true and a 60-90 s script.
  3. Wait 2-10 s: the TUI process exits with the uncaught exception below.
    The agent session itself continues; the user must restart the TUI to
    resume the session.

Observed timeline (2026-09-13, UTC in logs; local is UTC+2):

Time (UTC) Event
15:33:56 background task registered (60 s foreground-free probe)
15:33:58.987 TUI crash #1 - uncaught React error #185
15:37:51 background task registered (90 s) - no crash
15:40:19 background task registered (60 s)
15:40:23.476 TUI crash #2 - uncaught React error #185

The identical stack was also logged on 2026-09-09 with Qwen Code 0.23.2
(twice, 15:10:56 and 15:55:48 UTC).

Actual result

  • The TUI process terminates (uncaught exception, no error boundary).
  • All background child processes started by the agent are killed with it:
    their output files stay empty and the task status files remain stuck at
    "status": "running" forever, so in-flight background work is lost.
  • The user has to restart the TUI and resume the session.

Log evidence

From ~/.qwen/debug/<project-hash>.txt (current session, 2026-09-13):

2026-09-13T15:33:58.987Z [ERROR] [STARTUP] [UNCAUGHT_EXCEPTION] Minified React error #185; visit https://react.dev/errors/185 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
Error: Minified React error #185; visit https://react.dev/errors/185 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at getRootForUpdatedFiber (file:///.../node_modules/@qwen-code/qwen-code/chunks/chunk-O4KNCAX4.js:2315:70)
    at enqueueConcurrentHookUpdate (file:///.../node_modules/@qwen-code/qwen-code/chunks/chunk-O4KNCAX4.js:2296:16)
    at dispatchSetStateInternal (file:///.../node_modules/@qwen-code/qwen-code/chunks/chunk-O4KNCAX4.js:3479:20)
    at dispatchSetState (file:///.../node_modules/@qwen-code/qwen-code/chunks/chunk-O4KNCAX4.js:3453:9)
    at file:///.../node_modules/@qwen-code/qwen-code/chunks/chunk-O4KNCAX4.js:19589:5
    at emitLayoutListeners (file:///.../node_modules/@qwen-code/qwen-code/chunks/chunk-O4KNCAX4.js:14109:5)
    at resetAfterCommit (file:///.../node_modules/@qwen-code/qwen-code/chunks/chunk-O4KNCAX4.js:14497:5)
    at flushMutationEffects (file:///.../node_modules/@qwen-code/qwen-code/chunks/chunk-O4KNCAX4.js:7816:65)
    at commitRoot (file:///.../node_modules/@qwen-code/qwen-code/chunks/chunk-O4KNCAX4.js:7798:11)
    at commitRootWhenReady (file:///.../node_modules/@qwen-code/qwen-code/chunks/chunk-O4KNCAX4.js:7318:9)

(The second crash at 15:40:23.476Z has the byte-identical stack.)

Analysis

Facts:

  • The exception is thrown by React itself while committing a render:
    setState is dispatched from a layout-effect listener
    (emitLayoutListeners -> dispatchSetState -> ... -> commitRoot), i.e. a
    component sets state during commit, which schedules a new render, which
    runs the same layout effect again, until React's nested-update limit is
    hit and fix e2e #185 is thrown.
  • The stack shows enqueueConcurrentHookUpdate: the state update comes from
    a hook (useState/useReducer setter) called from a layout effect.
  • Both observed crashes land 2-4 s after a background task is registered,
    i.e. exactly when the TUI updates its background-task UI (new task in the
    list / status pill change). One registration and a long foreground command
    did not trigger it, so the loop likely depends on the UI state at
    registration time (e.g. which dialog/pill is mounted or focused).

Leading hypothesis (not confirmed - minified bundle): a setState call in a
layout effect of the background-tasks UI component runs unconditionally on
every commit (missing guard / missing effect dependencies / setting state to
a new object each time), producing the infinite update loop.

Suggested fixes

  1. Find and fix the self-rescheduling setState in the layout effect that
    reacts to background-task registration (guard the update, compare values,
    or fix the effect dependencies).
  2. Add an error boundary around the Ink root so a React rendering error can
    never kill the whole TUI process again.

Secondary observation (separate class, same logs)

The same debug-log files contain uncaught write EIO exceptions in the Ink
log-write path (2026-09-05 through 2026-09-09, versions 0.23.1-0.23.3):

2026-09-08T22:22:41.105Z [ERROR] [STARTUP] [UNCAUGHT_EXCEPTION] write EIO
Error: write EIO
    at afterWriteDispatched (node:internal/net:1509:15)
    ...
    at WritableStream.optimizedWrite (file:///.../chunks/startInteractiveUI-LR7K2ARZ.js:33209:26)
    at WritableStream.reflowWrite [as write] (file:///.../chunks/startInteractiveUI-LR7K2ARZ.js:33384:26)
    at Ink.throttledLog.throttle.leading (file:///.../chunks/chunk-O4KNCAX4.js:18137:29)

A failed TTY write (e.g. terminal closed/detached) should be handled
gracefully instead of becoming an uncaught exception.

What did you expect to happen?

Expected result

The TUI renders the new background task (task list / status pill) without
crashing. At minimum, a React error should not be able to kill the whole
process (error boundary around the Ink root).

Client information

Environment

  • Qwen Code: 0.23.3 (npm global, installed via fnm). The identical crash
    (same error code, same stack) was also logged on 2026-09-09 with 0.23.2.
  • Bundled React: 19.2.0 (version string present in the bundled chunk
    chunks/chunk-O4KNCAX4.js)
  • Node: v24.19.0 (fnm)
  • OS: Linux (Fedora 44), kernel 7.1.13-200.fc44.x86_64, x86_64

Login information

No response

Anything else we need to know?

No response

Activity

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

Metadata

Metadata

Assignees

Labels

category/uiUser interface and displaypriority/P1High priority issuescope/renderingDisplay and rendering logictype/bugSomething isn't working as expected

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions