[GH-ISSUE #1388] [Bug] vol2/lab_05_dist_train: silent Pyodide hang in WASM export — no widgets render #4399

Closed
opened 2026-04-19 12:25:07 -05:00 by GiteaMirror · 0 comments
Owner

Originally created by @profvjreddi on GitHub (Apr 17, 2026).
Original GitHub issue: https://github.com/harvard-edge/cs249r_book/issues/1388

summary

found during a local end-to-end audit of all 33 labs: labs/vol2/lab_05_dist_train.py exports fine, boots Pyodide without any console error, and its marimo shell attaches — but the interactive tabs / sliders / radios NEVER render. the lab is effectively non-functional in WASM mode.

repro

  1. cd mlsysim && python3 -m build --wheel
  2. Copy the wheel to /tmp/wasm/wheels/.
  3. marimo export html-wasm labs/vol2/lab_05_dist_train.py -o /tmp/wasm/lab_05/index.html --mode run --no-show-code
  4. Serve /tmp/wasm with COEP/COOP headers (see labs/tests/browser_smoke.py).
  5. Open /lab_05/index.html in headless Chromium via Playwright.
  6. Wait 2 minutes. [role=\"tab\"] count stays at 0.

diagnostics

  • marimo check vol2/lab_05_dist_train.py → exit 0
  • test_static.py + test_engine.py (both via app.run()) → pass
  • browser_smoke.py → passes with 'Pyodide settled in 5.0s (captured errors: 0)'
  • local DOM probe after 2 min: tabs=0 radios=0 sliders=0
  • console: no pageerror, no console.error, no {\"type\":\"exception\"} payload
  • load sequence identical to a working lab (lab_02_ml_systems) up to 'Loaded rich'
  • kernel messages diverge: lab_02 emits ~84, lab_05 stops at ~66 — suggests execution stalls after a specific cell

not caused by recent PRs

the WASM bootstrap in this file is identical to the state after #1353 (6d56fff7a, 'import plotly.subplots AFTER micropip install'). PR #1386 only reordered its return tuples alphabetically; it did not change the bootstrap or any cell logic.

what to investigate

  • which cell between #66 and #67 (approximately) stalls. add print markers or use marimo's --mode edit export to get cell-level logs.
  • whether pint, plotly.subplots, or one of the mlsysim.core.defaults imports blocks in the WASM runtime for this lab specifically.
  • whether the big tabs cell (~1400 lines in a single function) hits any Pyodide recursion limit when marimo analyses it.

why existing guards missed this

  • static / engine / marimo check all run in native Python, never touch Pyodide.
  • the #1374 browser smoke only checks for exceptions + shell attach. a silent await hang throws no error and the shell element attaches anyway.
  • CI ran green on this lab in #1374 and #1386 for the same reason.

extend labs/tests/browser_smoke.py to assert a minimum [role=\"tab\"] count on labs that declare mo.ui.tabs(...). any lab where the tabs element fails to render after a 60s wait should fail CI.

found this while running a full 33-lab audit. the other 32 labs render correctly.

Originally created by @profvjreddi on GitHub (Apr 17, 2026). Original GitHub issue: https://github.com/harvard-edge/cs249r_book/issues/1388 ## summary found during a local end-to-end audit of all 33 labs: `labs/vol2/lab_05_dist_train.py` exports fine, boots Pyodide without any console error, and its marimo shell attaches — but the interactive tabs / sliders / radios NEVER render. the lab is effectively non-functional in WASM mode. ## repro 1. `cd mlsysim && python3 -m build --wheel` 2. Copy the wheel to `/tmp/wasm/wheels/`. 3. `marimo export html-wasm labs/vol2/lab_05_dist_train.py -o /tmp/wasm/lab_05/index.html --mode run --no-show-code` 4. Serve `/tmp/wasm` with COEP/COOP headers (see `labs/tests/browser_smoke.py`). 5. Open `/lab_05/index.html` in headless Chromium via Playwright. 6. Wait 2 minutes. `[role=\"tab\"]` count stays at 0. ## diagnostics - `marimo check vol2/lab_05_dist_train.py` → exit 0 - `test_static.py` + `test_engine.py` (both via `app.run()`) → pass - `browser_smoke.py` → passes with 'Pyodide settled in 5.0s (captured errors: 0)' - local DOM probe after 2 min: `tabs=0 radios=0 sliders=0` - console: no `pageerror`, no `console.error`, no `{\"type\":\"exception\"}` payload - load sequence identical to a working lab (lab_02_ml_systems) up to 'Loaded rich' - kernel messages diverge: lab_02 emits ~84, lab_05 stops at ~66 — suggests execution stalls after a specific cell ## not caused by recent PRs the WASM bootstrap in this file is identical to the state after #1353 (6d56fff7a, 'import plotly.subplots AFTER micropip install'). PR #1386 only reordered its return tuples alphabetically; it did not change the bootstrap or any cell logic. ## what to investigate - which cell between #66 and #67 (approximately) stalls. add `print` markers or use marimo's `--mode edit` export to get cell-level logs. - whether pint, plotly.subplots, or one of the `mlsysim.core.defaults` imports blocks in the WASM runtime for this lab specifically. - whether the big tabs cell (~1400 lines in a single function) hits any Pyodide recursion limit when marimo analyses it. ## why existing guards missed this - static / engine / marimo check all run in native Python, never touch Pyodide. - the #1374 browser smoke only checks for exceptions + shell attach. a silent `await` hang throws no error and the shell element attaches anyway. - CI ran green on this lab in #1374 and #1386 for the same reason. ## recommended follow-up guard extend `labs/tests/browser_smoke.py` to assert a minimum `[role=\"tab\"]` count on labs that declare `mo.ui.tabs(...)`. any lab where the tabs element fails to render after a 60s wait should fail CI. found this while running a full 33-lab audit. the other 32 labs render correctly.
GiteaMirror added the link-healthtype: bugarea: website labels 2026-04-19 12:25:08 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/cs249r_book#4399