Skip to content

Avoid TypeError in ObservableGit when gitApi.repositories is transiently nullish#313571

Merged
bryanchen-d merged 3 commits intomainfrom
copilot/fix-unhandled-error-typeerror
Apr 30, 2026
Merged

Avoid TypeError in ObservableGit when gitApi.repositories is transiently nullish#313571
bryanchen-d merged 3 commits intomainfrom
copilot/fix-unhandled-error-typeerror

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 30, 2026

Telemetry reports an unhandled TypeError: e is not iterable originating from ArrayMap.setItems inside mapObservableArrayCached. The minified stack (BOe.setItemsWd._computeFnrecomputeInitiallyAndOnChangeinit) maps to ObservableGit.init in the Copilot Chat extension. Although the typing chain is fully non-null (mapObservableArrayCached takes IObservable<readonly TIn[]>, and repos is built from gitApi.repositories typed Repository[]), the git extension API can transiently return undefined from its repositories getter (e.g. during extension reload), violating its own type contract and propagating a nullish value into ArrayMap.setItems's for...of loop.

Description

  • extensions/copilot/src/platform/inlineEdits/common/observableGit.ts — coerce a nullish gitApi.repositories to [] at the boundary where the git extension API is consumed. This is the actual point in the chain where reality diverges from the declared typing, so the guard belongs here rather than in the generic observable utility.
const repos = observableFromEvent(this, (e) => gitApi.onDidOpenRepository(e), () => gitApi.repositories ?? []);

The generic mapObservableArrayCached utility is left unchanged, preserving its readonly TIn[] contract so future violations elsewhere are not silently masked.

…vable yields nullish

Agent-Logs-Url: https://github.com/microsoft/vscode/sessions/bbec7783-1ebc-4174-b1ab-02e8d2edf814

Co-authored-by: bryanchen-d <41454397+bryanchen-d@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot April 30, 2026 19:11
Copilot AI changed the title [WIP] Fix unhandled error: e is not iterable Avoid TypeError in mapObservableArrayCached when source observable yields nullish Apr 30, 2026
Copilot AI requested a review from bryanchen-d April 30, 2026 19:12
@bryanchen-d
Copy link
Copy Markdown
Contributor

@copilot why not fix it in extensions/copilot/src/platform/inlineEdits/common/observableGit.ts? what's the typing of items.read() returns? I think we should fix the typing if anywhere in the chain of flow that assign an nullish value while it is not supposed to be null by typing

Copilot AI requested review from Copilot and removed request for Copilot April 30, 2026 20:18
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 30, 2026

@copilot why not fix it in extensions/copilot/src/platform/inlineEdits/common/observableGit.ts? what's the typing of items.read() returns? I think we should fix the typing if anywhere in the chain of ...

Good point — moved the fix into observableGit.ts and reverted the generic mapObservableArrayCached change in 0c88a1f.

The typing chain is all non-null: mapObservableArrayCached takes IObservable<readonly TIn[]>, repos is built from gitApi.repositories which is typed Repository[]. The runtime nullish must therefore originate from the git extension's repositories getter returning undefined in some transient state (e.g. extension reloading), violating its own type contract. I can't fix the upstream git.d.ts typing without making every consumer handle nullish, so I added ?? [] at the boundary where we consume that API.

Copilot AI changed the title Avoid TypeError in mapObservableArrayCached when source observable yields nullish Avoid TypeError in ObservableGit when gitApi.repositories is transiently nullish Apr 30, 2026
@bryanchen-d bryanchen-d marked this pull request as ready for review April 30, 2026 21:04
Copilot AI review requested due to automatic review settings April 30, 2026 21:04
@bryanchen-d bryanchen-d enabled auto-merge April 30, 2026 21:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens Copilot Chat’s ObservableGit initialization against a real-world Git extension API contract violation where gitApi.repositories can be transiently undefined, preventing a TypeError: e is not iterable from propagating into mapObservableArrayCached/ArrayMap.setItems.

Changes:

  • Coerce gitApi.repositories to [] at the Git API consumption boundary in ObservableGit.init.
Show a summary per file
File Description
extensions/copilot/src/platform/inlineEdits/common/observableGit.ts Guards against transiently nullish gitApi.repositories by defaulting to an empty array when creating the repos observable.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment thread extensions/copilot/src/platform/inlineEdits/common/observableGit.ts
@bryanchen-d bryanchen-d merged commit cd83bc8 into main Apr 30, 2026
30 checks passed
@bryanchen-d bryanchen-d deleted the copilot/fix-unhandled-error-typeerror branch April 30, 2026 23:08
@vs-code-engineering vs-code-engineering Bot added this to the 1.119.0 milestone Apr 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Error] [GitHub.copilot-chat] unhandlederror-e is not iterable TypeError: e is not iterable at BOe.setItems (<REDACTED: user-fil...

4 participants