Skip to content

fix: guard against null diagnostic code in Copilot CLI diagnosticsChanged (fixes #332348) #332353

Description

@vs-code-engineering

Summary

The Copilot CLI diagnostics-changed notification crashes with TypeError: Cannot read properties of null (reading 'value') when serializing a diagnostic whose code is null. getDiagnosticsForUri uses typeof d.code === 'object' ? d.code.value : d.code, but typeof null === 'object' is true, so a null code falls into the object branch and dereferences null.value. Language servers and extensions are free to set Diagnostic.code to null, so this fires whenever such a diagnostic changes while a Copilot CLI session is active (50 users / 251 hits, new in extension 0.62.0).

Fixes #332348
Recommended reviewer: @alexweininger

Culprit Commit

Field Value
Commit ab48d553b302
Author @alexweininger
PR #3529
Message Migrate Copilot CLI integration (#3529)
Why This commit introduced getDiagnosticsForUri with the typeof d.code === 'object' ? d.code.value : d.code mapping at line 52. Because typeof null === 'object', a null code is routed into the object branch and .value is read off null. The code shipped in extension 0.62.0, which is when the bucket first appeared.

Code Flow

sequenceDiagram
    participant LS as Language Server / Extension
    participant API as vscode.languages.getDiagnostics
    participant Producer as getDiagnosticsForUri (map)
    participant CrashSite as d.code.value

    LS->>API: publishes Diagnostic with code = null
    API->>Producer: returns Diagnostic[] (code: null)
    Note over Producer: ⚠️ Root cause:<br/>typeof null === 'object' is true,<br/>so null enters the object branch
    Producer->>CrashSite: read d.code.value on null
    Note over CrashSite: TypeError: Cannot read<br/>properties of null (reading 'value')
Loading

Affected Files

File Role
extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/tools/push/diagnosticsChanged.ts Crash site and root cause — the code mapping on line 52

Repro Steps

  1. Open a Copilot CLI chat session so the diagnostics-changed notification is registered.
  2. Trigger a diagnostic from a language server/extension whose Diagnostic.code is null (rather than a string, number, or { value, target } object).
  3. When the diagnostics change fires, getDiagnosticsForUri maps the diagnostic and throws TypeError: Cannot read properties of null (reading 'value').

How the Fix Works

Chosen approachextensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/tools/push/diagnosticsChanged.ts:52: tighten the type test to typeof d.code === 'object' && d.code !== null so that a null code falls through to the : d.code branch and is emitted as null, instead of being dereferenced. This is the correct location because the code value crosses an external/untrusted boundary — vscode.languages.getDiagnostics returns data authored by arbitrary language servers and extensions, which the consumer cannot constrain — so the guard belongs at the point where the value is first narrowed and consumed. The fix is the standard typeof x === 'object' && x !== null idiom, preserves the existing behavior for real { value, target } code objects and for string/number codes, and does not swallow or hide any error.

Alternatives considered: wrapping the .map body in try/catch was rejected because it would silence a legitimate serialization failure and hide it from telemetry rather than correctly serializing a valid (null) code.

Recommended Owner

@alexweininger — authored the migration commit that introduced getDiagnosticsForUri, is a VS Code team member with write access, and has landed commits to microsoft/vscode within the last 90 days.

Generated by errors-fix · opus48 · 325.6 AIC · ⌖ 11.2 AIC · ⊞ 18.6K ·


Note

This was originally intended as a pull request, but PR creation failed. The changes have been pushed to the branch fix/diagnostics-null-code-332348-ab2b9bff63887b37.

Original error: ERR_API: [2026-08-24T15:50:52.676Z] create pull request in microsoft/vscode failed (attempt 1)

Original error: Validation Failed: {"resource":"PullRequest","code":"custom","field":"fork_collab","message":"fork_collab Fork collab can't be granted by someone without permission"} - https://docs.github.com/rest/pulls/pulls#create-a-pull-request
Retryable: false
Suggestion: This error cannot be resolved by retrying. Please check the error details and fix the underlying issue.

To create the pull request manually:

gh pr create --title "fix: guard against null diagnostic code in Copilot CLI diagnosticsChanged (fixes #332348)" --base main --head vscodebot-pr:fix/diagnostics-null-code-332348-ab2b9bff63887b37 --repo microsoft/vscode
Show patch (28 lines)
From 7a81b956bebe61fecadf6927fe46045d546a67a3 Mon Sep 17 00:00:00 2001
X-GH-AW-Base-Commit: 97bca284d0ced1deed71489e01589959b471fb73
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Mon, 24 Aug 2026 15:41:50 +0000
Subject: [PATCH] fix: guard against null diagnostic code in diagnosticsChanged

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 .../copilotcli/vscode-node/tools/push/diagnosticsChanged.ts     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/tools/push/diagnosticsChanged.ts b/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/tools/push/diagnosticsChanged.ts
index d0bfa4d2b35..70d64b7b082 100644
--- a/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/tools/push/diagnosticsChanged.ts
+++ b/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/tools/push/diagnosticsChanged.ts
@@ -49,7 +49,7 @@ function getDiagnosticsForUri(uri: vscode.Uri): DiagnosticInfo {
 			message: d.message,
 			severity: severityToString(d.severity),
 			source: d.source,
-			code: typeof d.code === 'object' ? d.code.value : d.code,
+			code: typeof d.code === 'object' && d.code !== null ? d.code.value : d.code,
 		})),
 	};
 }
-- 
2.54.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions