Explain figure rendering failures caused by kernel subshells - #597
Merged
Conversation
JupyterLab >= 4.4 routes widget messages over kernel subshells, which ipykernel >= 7 services on their own threads. Drawing a live canvas then races with figure creation during cell execution, and Matplotlib is not thread-safe. The resulting mathtext parse error gives users no hint of the cause or of the available workarounds. When laying out a canvas fails while subshells are active, chain the original error into one that names the cause and both workarounds, and document them alongside the installation instructions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Member
|
See also matplotlib/ipympl#621 |
nvaytet
reviewed
Jul 31, 2026
Member
There was a problem hiding this comment.
I have my reservations as to how useful these tests are. We are trying to make a workaround for an issue that we hope will be fixed upstream.
Creating these fakes that mimic some private or undocumented properties of ipykernel feels like they could get out of date without us noticing.
We are also faking the error from the canvas, so the tests seem quite remote from the actual behaviour?
Member
Author
There was a problem hiding this comment.
Should we try monkey-patching as in the PR you linked instead?
The runtime detection hooked the math text ParseException raised during tight_layout. That symptom is the one an ipympl-side parser lock removes; what survives the lock -- blank canvases and kernel crashes -- raises no exception, so the detection would catch nothing once ipympl releases. The workarounds are unchanged and remain the only complete fix, so keep them documented next to the installation instructions.
nvaytet
approved these changes
Aug 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Documents the JupyterLab subshell concurrency problem and its workarounds next to the installation instructions. Gives #596 the only answer plopp can give, and #499 a user-visible one.
JupyterLab >= 4.4 defaults to routing widget comm messages over kernel subshells, which ipykernel >= 7 services on their own threads. ipympl canvas draw/resize requests are then handled concurrently with cell execution, and Matplotlib is not thread-safe: a live canvas racing a figure build corrupts shared state. Symptoms are math text parse errors, blank figures, and kernel crashes, none of which point anywhere actionable. See ipympl#610 for the analysis.
There is no fix on our side. ipympl#621 locks Matplotlib's math text parser, which removes the parse errors, but the blank figures and crashes survive it: the frame path (
get_diff_imagereadingbuffer_rgba()) andhandle_resizestill run on the comm thread with no lockable API. SettingcommsOverSubshellstodisabledor pinningipykernel<7are the only workarounds verified to be fully stable, so those are what we document.An earlier version of this branch also chained the failure into an explanatory error at figure creation. That is dropped: it hooked the math text exception, which is exactly the symptom the ipympl lock removes, while what survives the lock raises nothing to hook.
Test plan