Summary
Generated interactive scenes can render correctly while being unusable because the generated JavaScript fails either:
- before execution (syntax / parse-time failure), or
- during interaction (runtime exception in generated state/data logic).
The current iframe runtime already captures runtime errors, but a broken interactive scene can still reach the user and remain effectively dead.
This is broader than the syntax-only case previously tracked in #1582 / #1583.
Real reproductions
I reproduced two independent real generated artifacts in a sandboxed browser path.
Case A: Flink realtime simulator — parse-time failure
The page visually renders a complete Flink simulation UI with sliders, Watermark / Checkpoint indicators, and a Start Simulation button.
The generated main script contains:
state counts = new Array(10).fill(0);
Browser result:
SyntaxError: Unexpected identifier 'counts'
Because the entire classic script fails to parse, handleMainButton() is never defined. Clicking the visible button then produces:
ReferenceError: handleMainButton is not defined
User-facing symptom: the page looks complete, but clicking Start Simulation does nothing.
Case B: data-pipeline game — runtime initialization failure
A separate generated game has syntactically valid JavaScript and renders normally.
After clicking Start Challenge, generated data references _REST API_, while the component registry contains REST API. The lookup returns undefined, then generated code reads comp.name and throws:
TypeError: Cannot read properties of undefined (reading 'name')
The interaction starts, partially initializes, then aborts.
Why this matters
These two artifacts have the same user-facing failure mode but different causes:
render succeeds
-> control is visible
-> generated JS is unusable
-> interaction appears dead / partially dead
A syntax-only fix addresses Case A but not Case B.
Current behavior
Proposed reliability boundary
I locally validated a two-layer approach:
Layer 1 — generation-time classic inline JS syntax preflight
Before persisting an interactive widget:
- compile-check classic inline
<script> bodies without executing them;
- skip data scripts such as
application/json;
- skip external
src scripts;
- skip
type="module" scripts;
- route failures through the existing
invalid-model-output retry path.
The real Flink artifact is rejected before persistence with:
script #9: Unexpected identifier 'counts'
Layer 2 — runtime-error-informed targeted repair
For syntax-valid pages that fail during interaction:
- reuse the existing iframe runtime-error capture;
- provide the current HTML plus concrete fatal runtime errors as repair context;
- regenerate only the interactive HTML;
- keep other scene data unchanged;
- run the repaired output through the same syntax preflight.
With the full runtime-broken game artifact, a local targeted repair produced a page that:
- passed syntax preflight;
- successfully started after clicking;
- rendered all expected component cards;
- emitted no page/runtime errors.
I intentionally kept the repair trigger user-initiated during local validation so normal playback does not automatically spend model quota.
Validation performed locally
Relevant regression coverage passed:
- iframe / picker / keep-alive / sandbox / repair-path tests: 42/42
- generation tests excluding the existing Windows-only assets path assertion: 149/149
- selected PBL / quiz / vocational routing regressions: 39/39
- generation package build: pass
- generation package typecheck: pass
- root
tsc --noEmit: pass
- focused ESLint: pass
git diff --check: pass
Syntax preflight cost on the two real artifacts was sub-millisecond (~0.07–0.20 ms per validation).
Architecture question
The generation-time syntax preflight is a narrow bug-fix boundary.
For runtime recovery, I would like maintainer guidance on the preferred integration point:
- a lightweight runtime failure affordance near the interactive renderer, or
- the existing MAIC Editor / agent editing path (e.g. the current interactive HTML editing plumbing).
I do not want to hard-code the UX/ownership before alignment, especially with #646 evolving the editor/agent architecture.
Related
Expected behavior
A generated interactive scene that is known to be invalid should not be persisted as an apparently functional widget.
If a syntactically valid scene fails at runtime, the captured error should be surfaced into an explicit recovery path rather than leaving a visually complete but unusable interaction.
Summary
Generated interactive scenes can render correctly while being unusable because the generated JavaScript fails either:
The current iframe runtime already captures runtime errors, but a broken interactive scene can still reach the user and remain effectively dead.
This is broader than the syntax-only case previously tracked in #1582 / #1583.
Real reproductions
I reproduced two independent real generated artifacts in a sandboxed browser path.
Case A: Flink realtime simulator — parse-time failure
The page visually renders a complete Flink simulation UI with sliders, Watermark / Checkpoint indicators, and a Start Simulation button.
The generated main script contains:
Browser result:
Because the entire classic script fails to parse,
handleMainButton()is never defined. Clicking the visible button then produces:User-facing symptom: the page looks complete, but clicking Start Simulation does nothing.
Case B: data-pipeline game — runtime initialization failure
A separate generated game has syntactically valid JavaScript and renders normally.
After clicking Start Challenge, generated data references
_REST API_, while the component registry containsREST API. The lookup returnsundefined, then generated code readscomp.nameand throws:The interaction starts, partially initializes, then aborts.
Why this matters
These two artifacts have the same user-facing failure mode but different causes:
A syntax-only fix addresses Case A but not Case B.
Current behavior
Proposed reliability boundary
I locally validated a two-layer approach:
Layer 1 — generation-time classic inline JS syntax preflight
Before persisting an interactive widget:
<script>bodies without executing them;application/json;srcscripts;type="module"scripts;invalid-model-outputretry path.The real Flink artifact is rejected before persistence with:
Layer 2 — runtime-error-informed targeted repair
For syntax-valid pages that fail during interaction:
With the full runtime-broken game artifact, a local targeted repair produced a page that:
I intentionally kept the repair trigger user-initiated during local validation so normal playback does not automatically spend model quota.
Validation performed locally
Relevant regression coverage passed:
tsc --noEmit: passgit diff --check: passSyntax preflight cost on the two real artifacts was sub-millisecond (~0.07–0.20 ms per validation).
Architecture question
The generation-time syntax preflight is a narrow bug-fix boundary.
For runtime recovery, I would like maintainer guidance on the preferred integration point:
I do not want to hard-code the UX/ownership before alignment, especially with #646 evolving the editor/agent architecture.
Related
Expected behavior
A generated interactive scene that is known to be invalid should not be persisted as an apparently functional widget.
If a syntactically valid scene fails at runtime, the captured error should be surfaced into an explicit recovery path rather than leaving a visually complete but unusable interaction.