Skip to content

Handle CDN fetch failures in BYOK known-models lookup#312862

Open
Copilot wants to merge 4 commits intomainfrom
copilot/fix-unhandled-error-fetch-failed
Open

Handle CDN fetch failures in BYOK known-models lookup#312862
Copilot wants to merge 4 commits intomainfrom
copilot/fix-unhandled-error-fetch-failed

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 27, 2026

BYOKContrib._authChange invokes fetchKnownModelList (a fetch to main.vscode-cdn.net/extensions/copilotChat.json) fire-and-forget. When the CDN is unreachable, TypeError: fetch failed surfaces as unhandlederror-fetch failed in the errors dashboard.

Changes in extensions/copilot/src/extension/byok/vscode-node/byokContribution.ts:

  • fetchKnownModelList: try/catch around the fetch; logs and returns {} on failure so providers register with their built-in defaults. Also null/undefined-guards the parsed JSON before reading version/modelInfo.
  • _authChange: try/catch around provider registration; on failure resets _byokProvidersRegistered and clears registrations/providers so a subsequent auth change can retry cleanly.
  • Fire-and-forget call sites (constructor + onDidAuthenticationChange): .catch handlers with descriptive messages prevent any future async failure inside _authChange from escaping as an unhandled rejection.
  • Typing: replaces implicit any from .json() with { version?: number; modelInfo?: Record<string, BYOKKnownModels> }.
try {
    data = await (await fetcherService.fetch(URL, { method: 'GET', callSite: 'byok-known-models' })).json();
} catch (error) {
    this._logService.error(error, 'BYOK: Failed to fetch Copilot Chat known models list. Defaulting to empty list.');
    return {};
}

Copilot AI self-assigned this Apr 27, 2026
Copilot AI review requested due to automatic review settings April 27, 2026 18:18
Copilot AI review requested due to automatic review settings April 27, 2026 18:18
Copilot AI linked an issue Apr 27, 2026 that may be closed by this pull request
… error

Agent-Logs-Url: https://github.com/microsoft/vscode/sessions/0ef1e357-14a4-46b7-9b9c-5499bdd6ca30

Co-authored-by: bryanchen-d <41454397+bryanchen-d@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot April 27, 2026 18:24
Copilot AI requested review from Copilot and removed request for Copilot April 27, 2026 18:24
Copilot AI changed the title [WIP] Fix unhandled error for fetch failure Handle CDN fetch failures in BYOK known-models lookup Apr 27, 2026
Copilot AI requested a review from bryanchen-d April 27, 2026 18:25
@bryanchen-d bryanchen-d requested a review from lszomoru April 27, 2026 18:47
@lszomoru lszomoru removed their request for review April 27, 2026 19:08
@bryanchen-d bryanchen-d requested a review from lramos15 April 27, 2026 19:14
@bryanchen-d bryanchen-d marked this pull request as ready for review April 27, 2026 21:56
Copilot AI review requested due to automatic review settings April 27, 2026 21:56
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 BYOK provider initialization in the Copilot extension by ensuring CDN fetch failures (for the shared “known models” list) and other async errors don’t surface as unhandled promise rejections, allowing providers to register with built-in defaults when the CDN is unreachable.

Changes:

  • Adds .catch(...) handlers at fire-and-forget _authChange call sites to prevent unhandled rejections.
  • Wraps BYOK provider creation/registration in _authChange with try/catch and resets internal registration state on failure to enable retries.
  • Makes fetchKnownModelList resilient to fetch/JSON parse failures and unexpected response shapes, defaulting to {}.
Show a summary per file
File Description
extensions/copilot/src/extension/byok/vscode-node/byokContribution.ts Adds error handling and safer parsing around known-models CDN fetch and BYOK provider registration lifecycle.

Copilot's findings

Comments suppressed due to low confidence (1)

extensions/copilot/src/extension/byok/vscode-node/byokContribution.ts:110

  • fetchKnownModelList logs "fetched successfully" even when the response is missing/invalid and you default to an empty list (after logging a warn). This can make logs misleading during outages or schema changes. Consider logging success only when version === 1 and modelInfo is present, and using a different info/trace message when defaulting to {}.
		if (!data || data.version !== 1 || !data.modelInfo) {
			this._logService.warn('BYOK: Copilot Chat known models list is not in the expected format. Defaulting to empty list.');
			knownModels = {};
		} else {
			knownModels = data.modelInfo;
		}
		this._logService.info('BYOK: Copilot Chat known models list fetched successfully.');
		return knownModels;
  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment on lines 64 to +71
if (byokEnabled && !this._byokProvidersRegistered) {
this._byokProvidersRegistered = true;
// Update known models list from CDN so all providers have the same list
const knownModels = await this.fetchKnownModelList(this._fetcherService);
if (this._store.isDisposed) {
return;
}
this._providers.set(OllamaLMProvider.providerName.toLowerCase(), instantiationService.createInstance(OllamaLMProvider, this._byokStorageService));
this._providers.set(AnthropicLMProvider.providerName.toLowerCase(), instantiationService.createInstance(AnthropicLMProvider, knownModels[AnthropicLMProvider.providerName], this._byokStorageService));
this._providers.set(GeminiNativeBYOKLMProvider.providerName.toLowerCase(), instantiationService.createInstance(GeminiNativeBYOKLMProvider, knownModels[GeminiNativeBYOKLMProvider.providerName], this._byokStorageService));
this._providers.set(XAIBYOKLMProvider.providerName.toLowerCase(), instantiationService.createInstance(XAIBYOKLMProvider, knownModels[XAIBYOKLMProvider.providerName], this._byokStorageService));
this._providers.set(OAIBYOKLMProvider.providerName.toLowerCase(), instantiationService.createInstance(OAIBYOKLMProvider, knownModels[OAIBYOKLMProvider.providerName], this._byokStorageService));
this._providers.set(OpenRouterLMProvider.providerName.toLowerCase(), instantiationService.createInstance(OpenRouterLMProvider, this._byokStorageService));
this._providers.set(AzureBYOKModelProvider.providerName.toLowerCase(), instantiationService.createInstance(AzureBYOKModelProvider, this._byokStorageService));
this._providers.set(CustomOAIBYOKModelProvider.providerName.toLowerCase(), instantiationService.createInstance(CustomOAIBYOKModelProvider, this._byokStorageService));
try {
// Update known models list from CDN so all providers have the same list
const knownModels = await this.fetchKnownModelList(this._fetcherService);
if (this._store.isDisposed) {
return;
}
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

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

Potential race: _authChange captures byokEnabled before awaiting fetchKnownModelList(). If auth changes to disabled while the await is in-flight, the disable branch in a subsequent _authChange call can clear registrations, but the original call will still proceed to register providers afterward (leaving BYOK providers enabled even though BYOK is now disabled). Consider guarding with a “generation” token / in-flight promise check (like CopilotCLIModels does) or re-checking isBYOKEnabled(...) after the await and bailing out if it changed.

Copilot uses AI. Check for mistakes.
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-fetch failed

3 participants