fix: guard against null item.row after renderElement in listView (fixes #314134)#314546
fix: guard against null item.row after renderElement in listView (fixes #314134)#314546vs-code-engineering[bot] wants to merge 3 commits intomainfrom
Conversation
#314134) renderElement can trigger reentrant splice/dispose operations via event handlers, which may release item.row before insertItemInDOM completes. Add a null check after renderElement returns to prevent the TypeError. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Base:
|
There was a problem hiding this comment.
Pull request overview
Guards ListView.insertItemInDOM against a reentrant disposal scenario where renderElement can indirectly null out item.row before subsequent DOM access, preventing a TypeError crash during notebook cell list updates.
Changes:
- Add a post-
renderElementnull check foritem.rowand early-return to avoid dereferencingitem.row.domNode. - Document the reentrancy rationale inline to clarify why the guard is needed.
Show a summary per file
| File | Description |
|---|---|
| src/vs/base/browser/ui/list/listView.ts | Adds a defensive guard after renderElement to prevent null-row DOM access during reentrant list updates. |
Copilot's findings
- Files reviewed: 1/1 changed files
- Comments generated: 1
| // After renderElement, item.row may become null due to reentrant splice/dispose operations | ||
| if (!item.row) { | ||
| return; | ||
| } |
There was a problem hiding this comment.
Added a regression test in 66473ee2e63: the test uses a renderer whose renderElement triggers a reentrant splice (removing items mid-render), which nulls out item.row. The test verifies that insertItemInDOM does not throw thanks to the guard clause.
Generated by errors-fix-driver · ● 7.1M
There was a problem hiding this comment.
Addressed: added a regression test that uses a renderer whose renderElement triggers a reentrant splice (removing items mid-render), which nulls item.row. The test verifies insertItemInDOM does not throw thanks to the guard clause.
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
electronjs.org
To allow these domains, add them to the
network.allowedlist in your workflow frontmatter:
network:
allowed:
- defaults
- "electronjs.org"See Network Configuration for more information.
Generated by errors-fix-driver · ● 4.9M
Adds a test that verifies insertItemInDOM does not throw when renderElement triggers a reentrant splice that nulls item.row. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Follow-up: Automated AnalysisTrigger: cron_check_failed Analysis
Action NeededThe CI failures appear to be caused by the branch being stale relative to Recommended: Manually update the branch by merging
|
Follow-up: Automated AnalysisTrigger: cron_check_failed Analysis
Action NeededThe CI failures are caused by the branch being out of date with Once CI passes, the PR should be ready for reviewer approval from No code changes were pushed this cycle due to tooling limitations with merge commits.
|
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
A
TypeError: Cannot read properties of null (reading 'domNode')occurs in the list view'sinsertItemInDOMmethod when accessingitem.row.domNodeat line 1002 oflistView.ts. The error is triggered during notebook cell list splice operations whenrenderElementcauses reentrant event dispatch that disposesitem.rowbefore control returns. This is a pre-existing race condition that spiked 3.1x in 1.118.1 (355 users vs 116 in 1.117.0), affecting all platforms.Fixes #314134
Recommended reviewer:
@rebornixCulprit Commit
This is a pre-existing bug, not a recent regression. The bucket history shows hits across every stable release from 1.110.0 through 1.118.1. The
stable-anomalylabel reflects a 3.1x spike rather than a new introduction. No single culprit commit can be identified.Code Flow
sequenceDiagram participant VM as NotebookViewModel participant CellList as NotebookCellList participant LV as ListView VM->>CellList: onDidChangeViewCells event fires CellList->>LV: splice2 triggers _updateElementsInWebview LV->>LV: insertItemInDOM → renderElement Note over LV: ⚠️ Root cause: renderElement<br/>triggers reentrant events that<br/>dispose item.row LV->>LV: item.row.domNode accessed Note over LV: 💥 TypeError: Cannot read<br/>properties of null (reading 'domNode')Affected Files
src/vs/base/browser/ui/list/listView.tsinsertItemInDOM()line 1002src/vs/workbench/contrib/notebook/browser/view/notebookCellList.tssrc/vs/workbench/contrib/notebook/browser/viewModel/notebookViewModelImpl.tsRepro Steps
How the Fix Works
Chosen approach (
src/vs/base/browser/ui/list/listView.ts): Added a guard clauseif (!item.row) { return; }after therenderElementcall (line 998) and before the code that accessesitem.row.domNode(line 1002). Sinceitem.rowis declared asIRow | null(the type is already nullable), there is no upstream type-system bypass — the field legitimately becomes null when reentrant event handlers dispose the row during rendering. The guard prevents the crash by early-returning when this reentrancy occurs. This follows the principle that guards belong where the nullable contract is consumed, since there is no single producer to fix upstream (the reentrancy can originate from many event paths).Recommended Owner
@rebornix— primary notebook component owner and most frequent contributor to notebookCellList.tserrors-fix-driver — cycle 4
Trigger: manual · Head:
319c95890d8f94f30ff6a571cccac87945079626(319c958)listView.ts:1003(in scope — regression test)Push: yes · Copilot rerequested: yes
Ready gate: CI needs to re-run on new head; Copilot review pending on new head → not marking ready this cycle.
errors-fix-driver — cycle 5
Trigger: cron_check_failed · Head:
4363ca61e0467e650e8ddb0fe12b66b7149bfa2b(4363ca6)Compile & Hygienefailure (real)elparameter in test rendererLinux/Electron,macOS/Electron,Windows/Electron,Linux/Browser,macOS/Browser,Windows/BrowserfailureslistView.ts:1003Push: yes · Copilot rerequested: yes
Ready gate: CI needs to re-run on new head → not marking ready this cycle.
errors-fix-driver — cycle 6
Trigger: cron_check_failed · Head:
51b90d42b2af3fb295a9d9e52a8500c82cf14828(51b90d4)Compile & HygienefailureLinux/Electron,macOS/Electron,Windows/Electron,Linux/Browser,macOS/Browser,Windows/Browser)listView.ts:1003main, no merge conflictsPush: no (no code changes needed) · Copilot rerequested: no (no push)
Ready gate: CI failing, branch behind main → not marking ready this cycle. CI failures appear to cascade from
Compile & Hygiene; unable to access CI logs to diagnose root cause. Branch may need rebasing to pick up main changes before CI can pass.