Skip to content

fix: forward cell names and configs on external file reload (#8421)#8433

Draft
mscolnick wants to merge 1 commit intomainfrom
ms/keep-cell-config-on-reload
Draft

fix: forward cell names and configs on external file reload (#8421)#8433
mscolnick wants to merge 1 commit intomainfrom
ms/keep-cell-config-on-reload

Conversation

@mscolnick
Copy link
Contributor

When editing a .mo.py notebook externally while marimo edit --watch is
running, cell metadata like hide_code=True and cell function names were
silently dropped. The file watcher detected changes and reloaded code, but
only cell codes and IDs were sent to the frontend — names and configs were
discarded. On the next UI save, the frontend's stale state would overwrite
the file without the externally-added metadata.

Changes

Backend:

  • Add names and configs fields to UpdateCellCodesNotification (with
    defaults for backward compatibility)
  • Update EditModeReloadStrategy.handle_reload() to extract and forward
    cell names and configs in both lazy and autorun paths
  • Update AppFileManager.reload() to detect config-only and name-only
    changes (previously only compared code)

Frontend:

  • Update setCellCodes reducer to accept and apply optional names and
    configs from the notification
  • Pass names and configs from the WebSocket message handler

Closes #8421

When editing a `.mo.py` notebook externally while `marimo edit --watch` is
running, cell metadata like `hide_code=True` and cell function names were
silently dropped. The file watcher detected changes and reloaded code, but
only cell codes and IDs were sent to the frontend — names and configs were
discarded. On the next UI save, the frontend's stale state would overwrite
the file without the externally-added metadata.

## Changes

**Backend:**
- Add `names` and `configs` fields to `UpdateCellCodesNotification` (with
  defaults for backward compatibility)
- Update `EditModeReloadStrategy.handle_reload()` to extract and forward
  cell names and configs in both lazy and autorun paths
- Update `AppFileManager.reload()` to detect config-only and name-only
  changes (previously only compared code)

**Frontend:**
- Update `setCellCodes` reducer to accept and apply optional `names` and
  `configs` from the notification
- Pass `names` and `configs` from the WebSocket message handler

Closes #8421
@vercel
Copy link

vercel bot commented Feb 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
marimo-docs Ready Ready Preview, Comment Feb 23, 2026 3:00pm

Request Review

@github-actions github-actions bot added the bash-focus Area to focus on during release bug bash label Feb 23, 2026
@mscolnick mscolnick added the bug Something isn't working label Feb 23, 2026
@mscolnick mscolnick requested a review from Copilot February 23, 2026 15:14
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes loss of cell metadata (cell names and @app.cell(...) config like hide_code) when reloading a notebook due to external file edits while marimo edit --watch is running, by ensuring metadata is detected on reload and forwarded to the frontend.

Changes:

  • Extend the backend UpdateCellCodesNotification payload to optionally include names and configs, and send them during edit-mode reloads (lazy + autorun).
  • Improve reload change detection to consider name/config changes in addition to code changes.
  • Update frontend WebSocket handling + cell reducer to apply names/configs, with new tests for backward compatibility and metadata updates.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/_session/test_file_change_handler.py Adds/updates tests asserting reload forwards names/configs and reload detects name/config-only changes
marimo/_session/file_change_handler.py For edit-mode reload, collects and forwards cell names/configs (and sends update-codes in autorun path)
marimo/_session/notebook/file_manager.py Reload change detection now compares full cell data (code/name/config), not just code
marimo/_messaging/notification.py Adds names and configs fields (with defaults) to UpdateCellCodesNotification
packages/openapi/api.yaml Updates OpenAPI schema for UpdateCellCodesNotification to include names/configs; updates API version
packages/openapi/src/api.ts Updates generated TS types for UpdateCellCodesNotification with optional names/configs
frontend/src/core/websocket/useMarimoKernelConnection.tsx Passes names/configs through to setCellCodes on update-cell-codes notifications
frontend/src/core/cells/cells.ts Enhances setCellCodes reducer to optionally apply names/configs during code updates
frontend/src/core/cells/tests/cells.test.ts Adds reducer tests for names/configs application and backward compatibility
Comments suppressed due to low confidence (3)

packages/openapi/api.yaml:4473

  • The OpenAPI schema description for UpdateCellCodesNotification still frames this as “kiosk mode”, but this PR extends its use to edit-mode file reload syncing. Updating the description would prevent API docs from becoming inaccurate.
    UpdateCellCodesNotification:
      description: "Updates cell code contents (kiosk mode).\n\n    Attributes:\n\
        \        cell_ids: Cells to update.\n        codes: New code for each cell.\n\
        \        code_is_stale: If True, code was not executed on backend (output\
        \ may not match).\n        names: Cell names for each cell (optional, for\
        \ file reload).\n        configs: Cell configs for each cell (optional, for\
        \ file reload)."

packages/openapi/src/api.ts:5764

  • The generated TS docs for UpdateCellCodesNotification still describe it as kiosk-mode only, but it’s now also used for edit-mode reload syncing (names/configs are explicitly for that). Consider updating the comment text so consumers aren’t misled.
     *             cell_ids: Cells to update.
     *             codes: New code for each cell.
     *             code_is_stale: If True, code was not executed on backend (output may not match).
     *             names: Cell names for each cell (optional, for file reload).
     *             configs: Cell configs for each cell (optional, for file reload).
     */

marimo/_session/notebook/file_manager.py:126

  • AppFileManager.reload() now treats changes in code, config, and cell name as modifications, but the method docstring above still says it detects changes by comparing only IDs and code. Please update the docstring to match the new behavior to avoid confusion for future maintainers.
        # Check for added or modified cells (code, config, or name)
        for cell_id in current_cell_ids:
            if cell_id not in prev_cell_ids:
                changed_cell_ids.add(cell_id)
            else:
                new_data = self.app.cell_manager.get_cell_data(cell_id)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +665 to +673
class UpdateCellCodesNotification(Notification, tag="update-cell-codes"):
"""Updates cell code contents (kiosk mode).

Attributes:
cell_ids: Cells to update.
codes: New code for each cell.
code_is_stale: If True, code was not executed on backend (output may not match).
names: Cell names for each cell (optional, for file reload).
configs: Cell configs for each cell (optional, for file reload).
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UpdateCellCodesNotification is no longer kiosk-only (it is now also used to sync edits from --watch reloads), but the class docstring still says “(kiosk mode)”. Please update the description to reflect its broader usage so the schema/docs aren’t misleading.

Copilot uses AI. Check for mistakes.
Comment on lines +138 to +144
strategy = EditModeReloadStrategy(config_manager_autorun)
changed_cell_ids = {CellId_t("cell1")}

strategy.handle_reload(mock_session, changed_cell_ids=changed_cell_ids)

# Should send UpdateCellIdsRequest
assert mock_session.notify.call_count >= 1
# Should send at least UpdateCellIdsNotification and UpdateCellCodesNotification
assert mock_session.notify.call_count >= 2
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In test_edit_mode_reload_strategy_autorun, changed_cell_ids is hard-coded to {CellId_t("cell1")} even though cell IDs are generated (and the lazy test above retrieves the real IDs from app_file_manager.app.cell_manager). This makes the test less representative and can cause the strategy to treat a non-existent cell as deleted; consider using the actual cell IDs from the loaded app (same approach as the lazy test).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bash-focus Area to focus on during release bug bash bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cell metadata (hide_code, names) lost on external file edit with --watch

2 participants