Repository navigation
fix(tools): stop NotebookEdit reusing cell ids after a delete - #3371
Conversation
Inserted cells were named cell-{len+1}, which is still taken once any
cell but the last has been deleted, so a later edit by the returned id
went to the older cell instead.
Yeachan-Heo
left a comment
There was a problem hiding this comment.
Review
Fix confirmed: The change correctly addresses the cell id collision bug by searching for the first unused id starting from cells.len() + 1 instead of naively using that value.
Logic verification:
- Search terminates correctly via
.find() - No off-by-one errors: starts from
cells.len() + 1which is the right baseline - Handles non-cell-N ids (e.g., custom ids like 'cell-a'): collision check only affects numeric ids
- Replace and delete operations unaffected:
resolve_cell_indexstill finds cells by id correctly
Test coverage: Regression test extended with insert-after-delete scenario verifying cell-4 is correctly assigned when cells [cell-2, cell-3] exist.
No duplication found: make_cell_id is the only function in the codebase that generates notebook cell ids.
Local verification:
cargo fmt --all --check ✓
cargo clippy -p tools --all-targets -- -D warnings ✓
cargo test -p tools ✓ (120 tests)
CI check-runs: All 6 checks passing (build, cargo test, cargo fmt, cargo clippy, docs, windows smoke).
—
[repo owner's gaebal-gajae (clawdbot) 🦞]
|
Merged as — |
Summary
After a cell's deleted from anywhere but the end of a notebook,
NotebookEditcan give the next inserted cell an id that another cell already has. The agent's next edit by that id then goes to the older cell, so it rewrites or deletes one it never meant to touch.New ids are the cell count plus one, which is only guaranteed free while nothing's been deleted. Insert three cells, delete
cell-1, and the next insert comes back ascell-3too. Replacecell-3after that and it's the original third cell that changes, while the new one's left alone. Jupyter's own ids are random, so the clash is always with a cell the agent added earlier.This counts up from the same number until it finds a free one, so ids only change where they'd have clashed.
Anti-slop triage
cell-3, which is already taken, and with it the test passesVerification
toolscrate -cargo test -p toolspasses apart from three git tests that fail the same way onmainfor me (my git config won't let them commit in a temp repo), andcargo clippy -p tools --all-targetsandcargo fmt --all --checkare cleangit diff --checkpasses.Resolution gate