[BUG] NotebookEdit tool writes non-standard Jupyter Notebook format.
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When Claude Code uses NotebookEdit tool to edit a notebook cell, it changes the source formatting from JSON array to single string.
e.g. here is what Claude Code produces:
{
"cell_type": "markdown",
"id": "ec27bf33",
"source": "### Sample header\nThis is line 1 \nThis is line 2"
}
While the above is valid, the Jupyter interface on clicking Save or executing cell turns it into:
{
"cell_type": "markdown",
"id": "ec27bf33",
"source": [
"### Sample header\n",
"This is line 1 \n",
"This is line 2"
]
}
Issue
Claude Code's notebook formatting makes it difficult to use it interactively with Jupyter as any edit by Claude Code changes the entire notebook cell contents causing massive noisy diffs.
What Should Happen?
Claude's NotebookEdit tool should simply follow standard notebook formatting where cell source lines are JSON array. e.g.
{
"cell_type": "markdown",
"id": "ec27bf33",
"source": [
"### Sample header\n",
"This is line 1 \n",
"This is line 2"
]
}
This should be a straightforward change to NotebookEdit tool.
Error Messages/Logs
Steps to Reproduce
- Ask Claude Code to edit a notebook cell.
- Commit the changes.
- Open the notebook in Jupyter & execute the cell
- Look at git diff, the notebook file is changed even though content is untouched.
Above issue makes it impossible to use Claude's NotebookEdit capability alongside standard Jupyter.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
v2.1.110
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
5 Comments
NotebookEditwritingsourceas a single string instead of a JSON array is a format compliance bug — the Jupyter Notebook format specification (nbformat 4) requiressourceto be an array of strings where each element is a line of content. Writing a single string is technically valid JSON but non-standard Jupyter format, causing downstream tools (Jupyter UI, nbconvert, etc.) to convert it on first save.From an agent capability and output integrity perspective, this means Claude Code produces notebooks that look correct but are subtly different from what any other Jupyter tool would produce — and that difference causes spurious diffs on every save, contaminating git history with non-substantive format changes.
The correct
sourceformat:Each line of the cell content should be a separate array element, with
\nat the end of every line except the last. The last element has no trailing newline.Fix: The
NotebookEdittool's cell writer should split the content on newlines and produce an array, with\nappended to each element except the last:This produces standard nbformat-compliant output that matches what Jupyter itself would write, preventing the spurious diffs on first save.
Closing for now — inactive for too long. Please open a new issue if this is still relevant.
This problem still persists in Claude Code.
@ashwin-ant @dhollman @km-anthropic - can any of you please review and reopen? Issue was auto closed, and I do not have the permission to reopen on this repo.
Yeah, this is definitely something to fix. It basically means (git) diff tools do not work well with claude code produced jupyter notebook code.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.