calesthio/OpenMontage · error · RuntimeError

stage drawer did not open

Error message

stage drawer did not open

What it means

Raised by scripts/backlot_visual_eval.py's interaction smoke when clicking the first .stage element opens a .drawer but its rendered text does not contain the word 'research'. The check verifies the stage drawer actually populated with stage content (the expected first stage being research-related), not merely that a drawer element appeared — so this fires when the drawer opens empty, shows an error/loading state, or displays the wrong stage's data.

Source

Thrown at scripts/backlot_visual_eval.py:180

        report.append(result)
    return report


def run_interactions(capture_dir: Path) -> dict[str, Any]:
    """Run browser interaction smoke through Python Playwright."""
    from playwright.sync_api import sync_playwright

    screenshot = capture_dir / "interaction-smoke.png"
    with sync_playwright() as pw:
        browser = pw.chromium.launch(headless=True)
        page = browser.new_page(viewport={"width": 1560, "height": 1000})
        page.goto(f"http://127.0.0.1:{PORT}/p/the-last-lighthouse?static=1")
        page.wait_for_selector(".stage")
        page.locator(".stage").first.click()
        page.wait_for_selector(".drawer")
        drawer_text = page.locator(".drawer").inner_text()
        if "research" not in drawer_text:
            raise RuntimeError("stage drawer did not open")
        page.locator(".script-card").first.click()
        page.wait_for_selector(".modal-bg.open")
        page.keyboard.press("Escape")
        page.wait_for_function("() => !document.querySelector('.modal-bg')?.classList.contains('open')")
        if page.locator(".takes").count() < 1:
            raise RuntimeError("takes drawer not present on staged takes scene")
        replay_button = page.locator(".rp-btn", has_text="REPLAY RUN")
        if replay_button.count():
            replay_button.first.click()
            page.wait_for_selector('input[type="range"]')
            page.locator('input[type="range"]').fill("500")
        page.screenshot(path=str(screenshot), full_page=True)
        browser.close()
    return {"status": "passed", "screenshot": str(capture_dir / "interaction-smoke.png")}


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description=__doc__)

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Open http://127.0.0.1:{PORT}/p/the-last-lighthouse?static=1 manually, click a stage, and inspect what the drawer actually shows.
  2. If content is correct but the wording changed, update the expected substring in scripts/backlot_visual_eval.py.
  3. If the drawer is empty/loading, fix the underlying data load or add a wait for the content to populate before asserting.

Example fix

# before
if "research" not in drawer_text:
    raise RuntimeError("stage drawer did not open")

# after (match current content + wait for population)
page.wait_for_function("() => document.querySelector('.drawer')?.innerText.trim().length > 0")
if "research" not in page.locator(".drawer").inner_text().lower():
    raise RuntimeError("stage drawer did not open")
Defensive patterns

Strategy: validation

Validate before calling

drawer_text = page.locator(".drawer").inner_text()
expected_stage = "research"
if expected_stage not in drawer_text.lower():
    # drawer opened but content missing/wrong — dump actual text for diagnosis
    raise AssertionError(f"drawer content unexpected: {drawer_text[:200]!r}")

Try / catch

try:
    run_interaction_smoke()
except RuntimeError as e:
    if "stage drawer did not open" in str(e):
        # inspect capture_dir/interaction-smoke.png (if reached) or run manually to see actual drawer state
        log.error("Drawer content check failed — open the page manually and inspect .drawer text")
    raise

Prevention

When it happens

Trigger: Running the interaction smoke against the Backlot static page (?static=1) when stage data fails to load, the drawer component renders before data arrives, a refactor renamed stage content so 'research' no longer appears, or the clicked .stage resolves to a different stage than expected.

Common situations: Frontend refactor changing stage labels or drawer content structure; fixture data for 'the-last-lighthouse' missing or renamed; race where the smoke asserts text before async content renders.

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/0c8c038d3341a56e. Report an issue: GitHub.