fix: guard null diagnostic code in copilotcli diagnostics push (fixes #333772) - #333781
Conversation
There was a problem hiding this comment.
Pull request overview
Prevents Copilot CLI diagnostic push notifications from crashing when a diagnostic code is null.
Changes:
- Adds a null guard before reading a structured diagnostic code’s
value.
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Driver cycle recordederrors-fix-driver:cycle head:886cfb6d7f3b6dd7784a1b659b3d9869f39c5a4a |
Move the null diagnostic code regression coverage into the existing diagnosticsChanged.spec.ts suite so the Copilot vitest config (**/*.spec.ts) actually runs it, and drop the uncollected tools/push/test/diagnosticsChanged.test.ts. Revert the serializeDiagnostic export extraction that was only needed by the removed test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Driver cycle recordederrors-fix-driver:cycle head:bd41a6fc10f9e02acdb94ba649693217482b865a |
There was a problem hiding this comment.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
Note
This error may be related to your runner configuration. You can now configure runners for Copilot code review separately from Copilot cloud agent by creating a copilot-code-review.yml file with your setup steps. Read the docs for details.
|
The failing |
1f625ad
into
microsoft:main
Summary
A
TypeError: Cannot read properties of null (reading 'value')fires in the Copilot CLI diagnostics-push notification path (diagnosticsChanged.ts). When VS Code reports a diagnostic whosecodeisnull, the serialization code doestypeof d.code === 'object' ? d.code.value : d.code. Becausetypeof null === 'object', the ternary takes the object branch and dereferencesnull.value, throwing. The throw escapes throughArray.mapand theDelayertask, surfacing as an unhandled error for ~136 users on0.63.0.Fixes #333772
Recommended reviewer:
@DonJayamanneCulprit Commit
ab48d553b30@alexweiningerdiagnosticsChanged.tswith the linecode: typeof d.code === 'object' ? d.code.value : d.code. Thetypeof ... === 'object'test is true fornull, so anulldiagnostic code takes the object branch and dereferencesnull.value. It is an ancestor of the shipped commit08d4889.Code Flow
sequenceDiagram participant VSCode as vscode.languages participant Handler as onDidChangeDiagnostics participant Producer as getDiagnosticsForUri participant CrashSite as diagnostics.map(d => ...) VSCode->>Handler: DiagnosticChangeEvent (diagnostic.code === null) Handler->>Producer: event.uris.map(getDiagnosticsForUri) Note over Producer: Root cause: typeof null === 'object' is true Producer->>CrashSite: diagnostics.map(d => code from d.code.value) Note over CrashSite: TypeError: Cannot read properties of null (reading 'value')Affected Files
extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/tools/push/diagnosticsChanged.tscode: typeof d.code === 'object' ? d.code.value : d.code—typeof null === 'object'reachesnull.valueRepro Steps
codeisnull(many linters/language servers emit a diagnostic with no code, surfaced asnullrather thanundefined).onDidChangeDiagnosticshandler runsgetDiagnosticsForUri, maps the diagnostic, and evaluatestypeof d.code === 'object' ? d.code.value : d.code.typeof null === 'object', the code dereferencesnull.valueand throws the unhandledTypeError.How the Fix Works
Chosen approach —
diagnosticsChanged.tsL52: add an explicit&& d.code !== nullto the object-branch guard so anullcode falls through to the else branch and is emitted as-is:This fixes the bug at the data producer (the serialization of the diagnostic), which is exactly where the invalid dereference occurs — not at a crash site further down or via a
try/catchthat would swallow the error and break telemetry. The VS CodeDiagnostic.codetype isstring | number | { value; target }, but the runtime value can legitimately benull; the pre-existingtypeof ... === 'object'check simply forgot the classictypeof nullfootgun. Thenullcode now serializes tonull, matching the intent for a diagnostic with no structured code.Alternatives considered:
.map()intry/catch— rejected because it hides the error from the telemetry pipeline instead of fixing the data producer, and would silently drop every diagnostic in a batch once one is malformed.d.code?.valueoptional chaining — rejected because it still takes the object branch fornulland would emitundefinedrather than the intendednull, and does not express the actual invariant (nullis not a structured code object).Recommended Owner
@DonJayamanne— the dominant and currently-active contributor to the Copilot CLI (copilotcli) integration area inmicrosoft/vscode. The culprit author (@alexweininger) has no commits to the repo in the last 90 days, so ownership falls to the active area maintainer.