Skip to content

BOM character (U+FEFF) in telemetry.devDeviceId causes 'Language model unavailable' — all API requests fail with ByteString error #4908

@eddyv73

Description

@eddyv73

Bug Report

Environment

  • VS Code: 1.113.0 (arm64)
  • GitHub Copilot Chat: v0.42.2
  • OS: macOS 26.3.1 (Apple Silicon)

Problem

The Chat panel shows "Language model unavailable" and no language models can be resolved. All Copilot API requests fail silently.

Root Cause

The file ~/Library/Application Support/Code/User/globalStorage/storage.json contained a Unicode BOM character (U+FEFF, hex EF BB BF) prepended to the telemetry.devDeviceId value:

"telemetry.devDeviceId": "\uFEFFdeec2157-6fb9-4d61-b623-f5bc5131e91a"

The Copilot Chat extension reads this value and includes it as an HTTP header in API requests. Since U+FEFF (char code 65279) exceeds the ByteString limit of 255, Node.js's undici HTTP library rejects every request with:

TypeError: Cannot convert argument to a ByteString because the character at index 0 has a value of 65279 which is greater than 255.

Impact — Cascading failures

This single corrupted byte broke all Copilot functionality:

  1. _fetchModels → "Failed to fetch models" → cannot discover available models
  2. getCopilotAgentModels → remote agent loading fails
  3. getAllSessions → chat session history fails to load
  4. Model resolutionUnable to resolve chat model with family selection: gpt-4o-mini
  5. Final result → "Language model unavailable" in the Chat panel

How to Reproduce

  1. Close VS Code
  2. Edit ~/Library/Application Support/Code/User/globalStorage/storage.json
  3. Add a BOM (\uFEFF) before the UUID in telemetry.devDeviceId
  4. Open VS Code → Open Copilot Chat → Send any message
  5. Observe "Language model unavailable"

Fix Applied (manual workaround)

Removed the BOM from the telemetry.devDeviceId value in storage.json. After restarting VS Code, all models resolved correctly (claude-opus-4.5, gpt-4o-mini, etc.).

Suggested Improvements

  1. Sanitize header values: Strip BOM/non-ASCII characters from values read from storage.json before using them as HTTP headers. A simple .replace(/\uFEFF/g, '') would prevent this class of failure.
  2. Validate on write: When writing telemetry.devDeviceId, ensure the value is a clean UUID without invisible characters.
  3. Better error reporting: Instead of silently failing all requests and showing "Language model unavailable", surface the actual ByteString error to the user in the Output panel so it can be diagnosed.
  4. Graceful degradation: If the device ID header fails, fall back to a request without it rather than blocking all functionality.

Logs

Extension Host log (before fix):

TypeError: Cannot convert argument to a ByteString because the character at index 0 has a value of 65279 which is greater than 255.

Extension Host log (after fix):

ccreq:ee04c8dc | success | claude-opus-4-5-20251101 | 3592ms | [panel/editAgent]
ccreq:862717e5 | success | gpt-4o-mini-2024-07-18 | 418ms | [copilotLanguageModelWrapper]

Unknown

I don't know how the BOM got into storage.json in the first place. It may have been introduced by another extension, a file sync tool, or a VS Code update. It would be worth investigating whether VS Code core or another component could be writing BOM-prefixed values to this file.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions