fix: degrade Copilot CLI session listing when SDK native addon is unavailable on musl Linux (fixes #321635)#321643
Open
vs-code-engineering[bot] wants to merge 1 commit into
Conversation
…vailable (fixes #321635) On musl-based Linux (e.g. Alpine), the @github/copilot SDK LocalSessionManager constructor eagerly loads a native runtime addon that ships no linuxmusl-x64 prebuild, so it throws "Native addon 'runtime' not found". Because the session manager is a cached Lazy, every chat-sessions refresh re-awaited the same rejected promise and re-threw an unhandled error. Flag the session manager as permanently unavailable the first time it fails to initialize (still logged via logService.error), and have the automatic getAllSessions refresh return an empty list thereafter instead of re-throwing on every pass. The first failure and all user-initiated paths still log and throw. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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 Copilot CLI chat-sessions provider throws an unhandled
Error: Native addon "runtime" not found for linuxmusl-x64 ...on every session-list refresh for users on musl-libc Linux (e.g. Alpine). The third-party@github/copilotSDK'sLocalSessionManagerconstructor eagerly builds an experimentation / feature-flag service that loads a nativeruntime.nodeaddon, and the SDK ships nolinuxmusl-x64prebuild. Because the session manager is a cachedLazy, the rejected promise is reused, so eachprovideChatSessionItemsrefresh re-awaits it and re-throws.Telemetry for this bucket: 11,193 hits / 2,747 users, present from
1.124.0through1.125.0(≈4 hits/user, consistent with repeated refreshes per session).This change marks the session manager permanently unavailable the first time initialization fails (still logged via
logService.error) and short-circuits the automatic refresh path to an empty list thereafter, so the feature degrades to "no CLI sessions" on unsupported platforms instead of repeatedly reporting an unhandled error. The first failure and all user-initiated paths still log and throw unchanged.Fixes #321635
Recommended reviewer:
@joshspicerCulprit Commit
Not precisely identifiable from the shallow CI clone (grafted to a single commit; no git history available for
git blame). Telemetry first recorded this bucket in1.124.0-insiderbuilds on 2026-06-03 (e.g. commitf5d16d03...) and it is present through1.125.0, indicating the trigger landed during the 1.124 milestone — most plausibly when the Copilot CLI chat-sessions provider began enumerating sessions on startup, which constructs the SDKLocalSessionManagerand eagerly loads the experimentation native addon. The throw itself originates in third-party SDK code (@github/copilot/sdk), which cannot be patched from this repository.Code Flow
flowchart TD A["MainThread → $refreshChatSessionItems"] --> B["ExtHostChatSessions.refreshHandler<br/>(no try/catch)"] B --> C["CopilotCLIChatSessionsContribution.provideChatSessionItems"] C --> D["CopilotCLISessionService.getAllSessions"] D --> E["_getAllSessions → getSessionManager()"] E --> F["_sessionManager Lazy:<br/>new internal.LocalSessionManager(...)"] F --> G["SDK createFeatureFlagService<br/>loads native runtime.node addon"] G --> H["throw: Native addon 'runtime'<br/>not found for linuxmusl-x64"] H -. "cached rejected promise reused<br/>on every refresh" .-> E H ==> I["Unhandled error → telemetry<br/>(escapes at refreshHandler)"]Affected Files
extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSessionService.ts— modified. Adds an availability flag set when the session manager fails to initialize, plus a guard clause in the automaticgetAllSessionsrefresh path.Repro Steps
@github/copilotships nolinuxmusl-x64native runtime prebuild.Native addon "runtime" not found for linuxmusl-x64 ...reported on each refresh.How the Fix Works
Chosen approach —
extensions/copilot/src/extension/chatSessions/copilotcli/node/copilotcliSessionService.ts:_sessionManagerLazy, which constructsnew internal.LocalSessionManager(...). On musl this throws, and becauseLazycaches the rejected promise the manager is permanently unavailable for the window's lifetime. A new_sessionManagerUnavailablefield is set inside thatLazy's existingcatch— the same place that already callslogService.error(...)and re-throws — so the first failure and every user-initiated path (resolve / create a session) still log and throw exactly as before.provideChatSessionItems→getAllSessions. A guard clause at the top ofgetAllSessionsreturns an empty list once the manager is known-unavailable, so the automatic refresh degrades gracefully to "no CLI sessions" instead of re-awaiting the cached rejected promise and re-throwing.extHostChatSessionsboundary that every chat-session provider funnels through. It adds a guard clause rather than a symptom-silencingtry/catch, and it preserves the existinglogService.errorso telemetry still records the condition once per session.After this change, once the SDK session manager fails to initialize (logged at the
Lazycatch),getAllSessionsreturns[]on every subsequent refresh, soprovideChatSessionItems/refreshHandlercan no longer re-await the cached rejected promise and re-throw — eliminating the repeated unhandled error — while the first failure and all user-initiated paths continue to log and throw for telemetry.Alternatives considered:
provideChatSessionItems/refreshHandlerintry/catch: rejected — it sits at the shared core boundary used by every chat-session provider and would swallow genuine bugs from all of them, hiding the cause instead of guarding the specific unsupported-platform producer.process.reportglibc probing or/etc/alpine-releasesniffing) and duplicates platform knowledge the SDK's own addon loader already encodes; the SDK load is the authoritative availability signal._sessionManagerLazyretry on failure: rejected — the failure is permanent on unsupported platforms, so a retry would simply re-throw and would not address the repeated reporting.Recommended Owner
@joshspicer— owns "Chat Sessions → Extension API" in the VS Code team working-areas. The unhandled error escapes through the Chat Sessions extension API (extHostChatSessions.tsrefreshHandler/$refreshChatSessionItems), and the fix lives in the Copilot CLI session provider that integrates with that API. (@osortegaowns the "Chat Sessions View" UI, which is not where this enumeration failure occurs.)