[BUG] NotebookEdit drops the notebook's final newline and rewrites cells it did not touch, so every edit leaves churn that Jupyter undoes on the next save
Status Open
Reported on v2.1.295
Maintainer reply None cached
Activity 1 comment · opened Oct 10, 2026
What's Wrong?
Editing one cell with NotebookEdit changes the file in places outside that cell:
- The final newline is removed. Jupyter (nbformat) always ends the file with
\n. After any NotebookEdit,git diffshows\ No newline at end of file. - The edited cell's
sourcebecomes one string instead of the list of lines Jupyter writes. That is valid nbformat, but Jupyter writes it back as a list on its next save, so the cell shows up in the diff twice: once from Claude, once from Jupyter. - Untouched cells are re-serialized. In a notebook stored with
\uXXXXescapes (whatjson.dumpwrites by default), every non-ASCII character in every other cell is rewritten as raw UTF-8. A one-word edit to a code cell rewrote the Japanese in the markdown cell above it.
The notebook stays valid, but in a repo each edit produces a diff that is mostly noise, and the next save from Jupyter produces a second one.
What Should Happen?
Only the edited cell changes, and it is written the way nbformat writes it (a list of lines). The rest of the file stays byte-for-byte as it was, including the final newline.
Steps to Reproduce
- Save a notebook from Jupyter, or write one exactly as nbformat does (
json.dumps(nb, indent=1, sort_keys=True, ensure_ascii=False) + "\n";nbformat.writereproduces it byte for byte). Code cellb2has
``json``
"source": [
"x = 1\n",
"fruit = \"APPLE\""
]
- NotebookEdit,
cell_id: b2,new_source: "x = 1\nfruit = \"ORANGE\"". git diff:
```diff
- "source": [
- "x = 1\n",
- "fruit = \"APPLE\""
- ]
- "source": "x = 1\nfruit = \"ORANGE\""
...
-}
+}
\ No newline at end of file
```
nbformat.writeon the edited notebook does not give back the file NotebookEdit wrote, so opening and saving it in Jupyter changes it again.
For (3): the same edit on a notebook written with ensure_ascii=True turned "# \u898b\u51fa\u3057\n" in the markdown cell into "# 見出し\n".
Environment
- Claude Code 2.1.295 (Claude Desktop's Code tab), Windows 11
- NotebookEdit called directly; the model and prompt play no part
- The 2.1.296 changelog has no entry for this; I could not run 2.1.296 itself here
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗