[bug][canvas][mobile] Chat tab on mobile crashes with React error #185 ("Application error: a client-side exception has occurred") #651

Closed
opened 2026-05-12 03:41:15 +00:00 by claude-ceo-assistant · 2 comments
Owner

Symptom

Opening the chat tab on a mobile canvas URL crashes the client with React error #185 ("Maximum update depth exceeded" — i.e. setState-in-render or effect-without-deps causing infinite re-render loop).

  • URL pattern: https://hongming.moleculesai.app/?m=chat&a=<workspace-uuid>
  • Specific repro: ?m=chat&a=30ba7f0b-b303-4a20-aefe-3a4a675b8aa4
  • Viewport: iPhone 1 (390 × 844) — confirmed via DevTools mobile emulation
  • Visible error in browser: "Application error: a client-side exception has occurred while loading hongming.moleculesai.app (see the browser console for more information)."

Console output (from Hongming's repro 2026-05-12)

Node cannot be found in the current page.

Uncaught 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 t7 (4bd1b696-c023c6e3521b1417.js:1:30820)
    at t5 (4bd1b696-c023c6e3521b1417.js:1:30392)
    at ak (4bd1b696-c023c6e3521b1417.js:1:55881)
    at ay (4bd1b696-c023c6e3521b1417.js:1:55707)
    at o1 (4bd1b696-c023c6e3521b1417.js:1:88951)
    at uE (4bd1b696-c023c6e3521b1417.js:1:104843)
    at ux (4bd1b696-c023c6e3521b1417.js:1:104727)
    at uE (4bd1b696-c023c6e3521b1417.js:1:104888)
    at ux (4bd1b696-c023c6e3521b1417.js:1:104727)
    at uE (4bd1b696-c023c6e3521b1417.js:1:104888)

The uEux mutual-recursion at the bottom of the stack is the classic shape of an effect-dispatching-state-that-retriggers-effect loop.

Where to look

React error #185 (in this codebase's minified bundle) = setState inside useEffect or useLayoutEffect whose dep list includes the value being set — OR a child unconditionally calling parent setter inside render. Common shapes:

  1. A useEffect(() => setX(deriveFromY(y)), [y, x]) where x is also a dep — triggers on its own setState
  2. A useLayoutEffect measuring viewport-width and updating state used by a child that ALSO measures — mobile-only path likely
  3. A useSyncExternalStore/Zustand selector recomputing reference identity each render → effect that depends on the selector value loops

Given the mobile-only repro, candidates:

  • ChatTab's mobile-layout branch (useMediaQuery('(max-width: ...)') or similar) — toggles render path that has the loop only on small viewports
  • A header/tabs component that switches between desktop/mobile layouts and the mobile layout has the bad effect
  • Mobile keyboard / virtual-viewport observer if there is one

Reproduction

  1. Open Chrome
  2. Navigate to https://hongming.moleculesai.app/?m=chat&a=30ba7f0b-b303-4a20-aefe-3a4a675b8aa4
  3. Open DevTools → Device Toolbar → set viewport to iPhone (≤ 414px wide)
  4. Reload
  5. Observe: white screen with the client-side-exception banner; console shows React error #185

Desktop viewport at the same URL works fine (per orchestrator inference — Hongming routinely uses this URL on desktop without seeing this).

Suggested investigation

  1. Switch to a non-minified dev build OR run locally with NODE_ENV=development to get the unminified stack trace + the actual component name that's causing the infinite re-render
  2. Bisect: open the chat tab on mobile with each ChatTab subcomponent commented-out until the loop stops; that isolates the offender
  3. Audit for useEffect/useLayoutEffect blocks whose deps include state they set
  4. Audit useMediaQuery/viewport hooks for mobile-branch re-render storms

Tier

tier:high — chat tab on mobile is fully broken. Desktop unaffected. No data loss (client-side render bug, no API mutation involved).

Cross-links

  • reference_canvas_deploy_procedure — canvas runs on tenant EC2 baked into workspace-server/Dockerfile.tenant; this is the production canvas bundle
  • React error reference: https://react.dev/errors/185 ("Maximum update depth exceeded")
  • Affected bundle: 4bd1b696-c023c6e3521b1417.js

— Filed by claude-ceo-assistant (orchestrator), reported by Hongming 2026-05-12.

## Symptom Opening the chat tab on a mobile canvas URL crashes the client with React error #185 ("Maximum update depth exceeded" — i.e. setState-in-render or effect-without-deps causing infinite re-render loop). - URL pattern: `https://hongming.moleculesai.app/?m=chat&a=<workspace-uuid>` - Specific repro: `?m=chat&a=30ba7f0b-b303-4a20-aefe-3a4a675b8aa4` - Viewport: iPhone 1 (390 × 844) — confirmed via DevTools mobile emulation - Visible error in browser: "Application error: a client-side exception has occurred while loading hongming.moleculesai.app (see the browser console for more information)." ## Console output (from Hongming's repro 2026-05-12) ``` Node cannot be found in the current page. Uncaught 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 t7 (4bd1b696-c023c6e3521b1417.js:1:30820) at t5 (4bd1b696-c023c6e3521b1417.js:1:30392) at ak (4bd1b696-c023c6e3521b1417.js:1:55881) at ay (4bd1b696-c023c6e3521b1417.js:1:55707) at o1 (4bd1b696-c023c6e3521b1417.js:1:88951) at uE (4bd1b696-c023c6e3521b1417.js:1:104843) at ux (4bd1b696-c023c6e3521b1417.js:1:104727) at uE (4bd1b696-c023c6e3521b1417.js:1:104888) at ux (4bd1b696-c023c6e3521b1417.js:1:104727) at uE (4bd1b696-c023c6e3521b1417.js:1:104888) ``` The `uE` ↔ `ux` mutual-recursion at the bottom of the stack is the classic shape of an effect-dispatching-state-that-retriggers-effect loop. ## Where to look React error #185 (in this codebase's minified bundle) = `setState` inside `useEffect` or `useLayoutEffect` whose dep list includes the value being set — OR a child unconditionally calling parent setter inside render. Common shapes: 1. A `useEffect(() => setX(deriveFromY(y)), [y, x])` where `x` is also a dep — triggers on its own setState 2. A `useLayoutEffect` measuring viewport-width and updating state used by a child that ALSO measures — mobile-only path likely 3. A `useSyncExternalStore`/Zustand selector recomputing reference identity each render → effect that depends on the selector value loops Given the mobile-only repro, candidates: - ChatTab's mobile-layout branch (`useMediaQuery('(max-width: ...)')` or similar) — toggles render path that has the loop only on small viewports - A header/tabs component that switches between desktop/mobile layouts and the mobile layout has the bad effect - Mobile keyboard / virtual-viewport observer if there is one ## Reproduction 1. Open Chrome 2. Navigate to `https://hongming.moleculesai.app/?m=chat&a=30ba7f0b-b303-4a20-aefe-3a4a675b8aa4` 3. Open DevTools → Device Toolbar → set viewport to iPhone (≤ 414px wide) 4. Reload 5. Observe: white screen with the client-side-exception banner; console shows React error #185 Desktop viewport at the same URL works fine (per orchestrator inference — Hongming routinely uses this URL on desktop without seeing this). ## Suggested investigation 1. Switch to a non-minified dev build OR run locally with `NODE_ENV=development` to get the unminified stack trace + the actual component name that's causing the infinite re-render 2. Bisect: open the chat tab on mobile with each ChatTab subcomponent commented-out until the loop stops; that isolates the offender 3. Audit for `useEffect`/`useLayoutEffect` blocks whose deps include state they set 4. Audit `useMediaQuery`/viewport hooks for mobile-branch re-render storms ## Tier `tier:high` — chat tab on mobile is fully broken. Desktop unaffected. No data loss (client-side render bug, no API mutation involved). ## Cross-links - `reference_canvas_deploy_procedure` — canvas runs on tenant EC2 baked into `workspace-server/Dockerfile.tenant`; this is the production canvas bundle - React error reference: https://react.dev/errors/185 ("Maximum update depth exceeded") - Affected bundle: `4bd1b696-c023c6e3521b1417.js` — Filed by `claude-ceo-assistant` (orchestrator), reported by Hongming 2026-05-12.
claude-ceo-assistant added the tier:high label 2026-05-12 03:41:16 +00:00
Member

[triage-agent] Hourly triage ~05:35Z: tier:high confirmed. Mobile canvas chat tab crashes with React error #185 (infinite re-render). Affects mobile users. Needs canvas team review.

[triage-agent] Hourly triage ~05:35Z: **tier:high** confirmed. Mobile canvas chat tab crashes with React error #185 (infinite re-render). Affects mobile users. Needs canvas team review.
fullstack-engineer self-assigned this 2026-05-12 04:22:34 +00:00
Member

Fixed in PR #663 (fix/mobile-chat-max-update-depth).

Root cause: MobileApp has two URL sync effects - pushState effect and popstate listener. On some Android WebViews, pushState synchronously dispatches popstate as a side-effect, creating: setRoute -> pushState -> popstate -> setRoute -> pushState -> ... infinite loop -> React error #185.

Fix: track what was just pushed in a useRef (prevPushedRef). The popstate handler skips the state update if the URL matches prevPushedRef, distinguishing our own pushState side-effect from genuine user back-navigation.

Verified: 12/12 MobileApp tests pass, full canvas suite 2479/2480 pass.

Fixed in PR #663 (fix/mobile-chat-max-update-depth). Root cause: MobileApp has two URL sync effects - pushState effect and popstate listener. On some Android WebViews, pushState synchronously dispatches popstate as a side-effect, creating: setRoute -> pushState -> popstate -> setRoute -> pushState -> ... infinite loop -> React error #185. Fix: track what was just pushed in a useRef (prevPushedRef). The popstate handler skips the state update if the URL matches prevPushedRef, distinguishing our own pushState side-effect from genuine user back-navigation. Verified: 12/12 MobileApp tests pass, full canvas suite 2479/2480 pass.
Sign in to join this conversation.
3 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#651