Skip to content

[Bug]: Generated interactive scenes can render but remain unusable after script/runtime failures #1622

Description

@Qnh233

Summary

Generated interactive scenes can render correctly while being unusable because the generated JavaScript fails either:

  1. before execution (syntax / parse-time failure), or
  2. 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.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions