fix: mark 'Language model unavailable' as expected chat error (fixes #326356)#326357
Open
vs-code-engineering[bot] wants to merge 1 commit into
Open
fix: mark 'Language model unavailable' as expected chat error (fixes #326356)#326357vs-code-engineering[bot] wants to merge 1 commit into
vs-code-engineering[bot] wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
chatAgentErrortelemetry bucketchatagenterror-Language model unavailablefires wheneverExtHostChatAgents2.getModelForRequestcannot resolve a language model for a chat request — thrown from$invokeAgent(and$detectChatParticipant). This is an expected operational condition (the user is not signed in, or no chat models have been contributed yet), not a code bug, but it was thrown as a genericErrorand therefore published to error telemetry as noise. The fix marks it as aChatExpectedErrorso the existing suppression path keeps it out ofchatAgentErrortelemetry while still surfacing the user-facing message.Fixes #326356
Recommended reviewer:
@bryanchen-dCulprit Commit
throw new Error('Language model unavailable')ingetModelForRequestis a long-standing pattern. TheisExpectedError/ChatExpectedErrorsuppression mechanism was added later (3727d0ce, "add isExpectedError flag to suppress expected agent errors from telemetry", by@bryanchen-d, 2026-04-27). This throw was simply never opted into that mechanism, so it continued surfacing as achatAgentErrorbucket. No single regression commit introduced the error path.Code Flow
sequenceDiagram participant Agent as Chat request participant Invoke as extHostChatAgents2.$invokeAgent participant Producer as getModelForRequest participant Main as mainThreadChatAgents2 Agent->>Invoke: invoke agent Invoke->>Producer: getModelForRequest(request, extension) Note over Producer: ⚠️ No user-selected model and<br/>getDefaultLanguageModel() returns undefined<br/>(user not signed in / no models) Producer-->>Invoke: throw new Error('Language model unavailable') Note over Invoke: 💥 Generic Error → errorCallstack packed,<br/>isExpectedError NOT set Invoke->>Main: rpcResult { errorCallstack, errorName } Note over Main: publishes chatAgentError telemetry<br/>(bucket: chatagenterror-Language model unavailable)Affected Files
src/vs/workbench/api/common/extHostChatAgents2.tsif (!model) { throw new Error('Language model unavailable'); }— expected condition thrown as generic Errorsrc/vs/workbench/api/common/extHostChatAgents2.tsgetModelForRequest/$invokeAgentsrc/vs/workbench/api/browser/mainThreadChatAgents2.tsif (rpcResult?.errorCallstack && !rpcResult.errorDetails?.isExpectedError) { ... publicLogError2('chatAgentError', ...) }— suppresses whenisExpectedErroris setRepro Steps
getModelForRequestresolves no user-selected model andgetDefaultLanguageModel()returnsundefined, sothrow new Error('Language model unavailable')fires.chatAgentErrortelemetry event, producing thechatagenterror-Language model unavailablebucket.How the Fix Works
Chosen approach —
src/vs/workbench/api/common/extHostChatAgents2.ts,getModelForRequest: the fix is applied at the data producer (where the invalid/expected state is first detected), not at the crash site or in a downstreamtry/catch. Instead of throwing a genericError, the "no model available" case now throws an error whosenameis set toChatExpectedError.$invokeAgentalready mapse.name === 'ChatExpectedError'toerrorDetails.isExpectedError = true, andmainThreadChatAgents2already skips publishing thechatAgentErrorevent when that flag is set (the existing suppression channel added for rate-limit / quota / connectivity / "cloud agent not enabled" conditions). This removes the bucket from error telemetry while preserving the user-facing message and thelogService.errorlog entry — no logging is removed and no error is swallowed in atry/catch.This is the intended use of the
ChatExpectedErrormechanism: a genuinely expected, user-actionable operational condition opts out of bug telemetry rather than being silenced.Alternatives considered:
logService.error(e, ...)call or thechatAgentErroremission on the message string'Language model unavailable'— rejected because string-matching in the consumer is brittle and puts the decision in the wrong place; the producer already knows the condition is expected.getModelForRequestcall in atry/catchthat returns a benign result — rejected because it hides the condition from the user-facing error surface and masks the state instead of classifying it.Recommended Owner
@bryanchen-d— owner of thechatAgentErrortelemetry event (owner: 'bryanchen-d'inmainThreadChatAgents2.ts) and author of theisExpectedError/ChatExpectedErrorsuppression mechanism this fix uses. Active VS Code team member; already assigned to the issue.