Skip to content

Marimo Notebook Compatibility

Several experiment notebooks needed small compatibility fixes for the current marimo validator before they could be executed headlessly.

Cell-local names

marimo check rejects repeated public variable names across cells, even when they are only loop temporaries. For shared notebook patterns like:

  • for algorithm in experiment["selected_algorithms"]
  • algo_experiment = experiment["experiments"][algorithm]

prefer underscore-prefixed temporaries instead:

  • _algorithm
  • _algo_experiment
  • _metrics
  • _blocks

This keeps the variables cell-private and avoids critical[multiple-definitions] errors.

No early return in control flow

Inside @app.cell blocks, return is part of marimo's cell-output syntax; it is not treated like normal Python control flow after marimo extracts the cell body. Patterns like:

if not experiment["selected_algorithms"]:
    print("No algorithms selected.")
    return

fail validation with critical[invalid-syntax]: 'return' outside function.

Use an else: block instead and keep a single return at the end of the cell.

Headless execution

marimo run ... starts a long-lived app server. For batch execution, prefer:

uv run marimo export html notebook.py -o /tmp/notebook.html

This executes the notebook to completion and exits, which is better suited to experiment smoke runs and CI-style verification.

Interactive play notebooks

Gridworld play*_mo.py notebooks should expose a top-level show_hud = True setting in the pygame cell, then copy it into mutable runtime state when the notebook uses a runtime_state dict. The HUD draw calls should be guarded by that state and may also be toggled at runtime with H.

Start pygame windows at a readable size by scaling the first rendered frame up to an initial_window_long_edge of about 880 pixels while preserving the frame aspect ratio. Keep pygame.RESIZABLE enabled so manual resizing still works.