Skip to content

Fix chat image attachments silently dropped when signed out of GitHub - #323856

Merged
Dmitriy Vasyura (dmitrivMS) merged 9 commits into
microsoft:mainfrom
samir-nimbly:fix/chat-image-attachments-signed-out
Jul 29, 2026
Merged

Fix chat image attachments silently dropped when signed out of GitHub#323856
Dmitriy Vasyura (dmitrivMS) merged 9 commits into
microsoft:mainfrom
samir-nimbly:fix/chat-image-attachments-signed-out

Conversation

@samir-nimbly

@samir-nimbly samir-nimbly commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Fixes #323854

Reported issue (#323854)

When using the built-in VS Code Chat without being signed in to a GitHub account, image attachments are not delivered to the configured model. The image renders in the composer, but on send the model responds as if nothing was attached:

No image was attached to your message. The <attachments> section is empty.

  • Reproduces with every attach method: drag-and-drop, clipboard paste, and the + button / file picker.
  • Reproduces with a configured multimodal BYOK / local model (e.g. a local OpenAI-compatible endpoint such as Minimax M3 or Qwen), so the model itself can consume image input.
  • Reproduces on both Windows 11 and Ubuntu, and with --disable-extensions, ruling out third-party extensions.

Control experiment (signed-out vs signed-in), same model, same steps:

Signed out of GitHub Signed in to GitHub
Active model Minimax M3 (multimodal) Minimax M3 (multimodal)
Image attached LocalImage.png LocalImage.png
Model response "No image was attached…" ❌ image described correctly ✅

The only variable is Chat sign-in state — the image is stripped client-side before the request reaches the provider.

Root cause

The panel Image prompt element (extensions/copilot/src/extension/prompts/node/panel/image.tsx) — which renders user-attached image variables into the outgoing request (via chatVariables.tsx) — gated image inclusion on:

if (!this.promptEndpoint.supportsVision || !this.authService.copilotToken?.isEditorPreviewFeaturesEnabled()) {
    // omit the image
}

copilotToken is undefined when there is no Copilot token — i.e. when the user is signed out. undefined?.isEditorPreviewFeaturesEnabled() is undefined, so !undefined is true, and the image is omitted before the request is dispatched, regardless of the model's actual vision capability. This is exactly why the same vision-capable BYOK model works signed in but drops images signed out.

isEditorPreviewFeaturesEnabled() represents an organization policy (it returns true unless a Copilot token explicitly sets editor_preview_features=0). It is only meaningful when a Copilot token exists. Applying it to the no-token case incorrectly blocks signed-out and BYOK users who have no Copilot entitlement at all.

Fix

Default the preview-features check to enabled when no Copilot token is present, using the same ?? true pattern already used in claudeChatSessionContentProvider.ts:

if (!this.promptEndpoint.supportsVision || !(this.authService.copilotToken?.isEditorPreviewFeaturesEnabled() ?? true)) {
    // omit the image
}

Applied to both the Image and HistoricalImage render paths.

Behavior after the fix

Scenario Before After
Signed out + vision-capable model image dropped ❌ image sent ✅
Signed in, preview features enabled image sent image sent ✅
Signed in, org policy editor_preview_features=0 image dropped image dropped ✅ (policy preserved)
Model without vision image dropped image dropped ✅

The organization-policy gate is fully preserved: a Copilot token that explicitly disables editor preview features still omits images.

Testing

Added extensions/copilot/src/extension/prompts/node/panel/test/image.spec.ts covering all four scenarios above (signed-out, signed-in, org-policy-disabled, non-vision model), mirroring the existing fileVariable.spec.ts harness.

Notes

  • The change is scoped to the two guard expressions; no behavior changes for signed-in users under any policy.
  • A repository-wide check confirmed image.tsx was the only place using the !copilotToken?.isEditorPreviewFeaturesEnabled() form without an explicit fallback.

Image attachments were silently dropped for signed-out users even when a
vision-capable BYOK/local model was configured. The panel Image prompt
element gated image inclusion on
`copilotToken?.isEditorPreviewFeaturesEnabled()`, which is `undefined`
when there is no Copilot token (i.e. not signed in), so the negation
evaluated truthy and the image was omitted before the request was sent.

`isEditorPreviewFeaturesEnabled()` represents an org policy that is only
meaningful when a Copilot token exists; a missing token should not block
the feature. Default the check to enabled when the token is absent, using
the same `?? true` pattern already used in
claudeChatSessionContentProvider. This preserves the org-policy behavior
(explicit `editor_preview_features=0` still omits images) while letting
signed-out / BYOK users send images to vision-capable models.

Applied to both HistoricalImage and Image render paths, and added unit
tests covering signed-out, signed-in, org-policy-disabled, and
non-vision-model cases.

Fixes microsoft#323854

Co-authored-by: SamirSaji <samirsaji13@gmail.com>
Copilot AI review requested due to automatic review settings July 1, 2026 10:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes a regression in the Copilot Chat prompt pipeline where image attachments were being omitted when the user was signed out (no Copilot token), even if the configured endpoint supports vision (BYOK/local multimodal models). The change aligns the “editor preview features” org-policy gate with its intended semantics by defaulting to enabled when no token is present.

Changes:

  • Update Image and HistoricalImage prompt-element guards to treat missing Copilot tokens as “preview features enabled” (?? true).
  • Add unit coverage for signed-out, signed-in, org-policy-disabled, and non-vision endpoint scenarios.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
extensions/copilot/src/extension/prompts/node/panel/image.tsx Fixes the guard logic so signed-out/BYOK users don’t have images dropped while preserving the org-policy disable path.
extensions/copilot/src/extension/prompts/node/panel/test/image.spec.ts Adds regression tests ensuring images are included/omitted correctly across auth + policy + capability combinations.

Comment thread extensions/copilot/src/extension/prompts/node/panel/image.tsx Outdated
@samir-nimbly

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

Address review feedback: when a vision-capable model has images omitted
because org policy disables editor preview features, the omitted-reference
status previously said the model "does not support images", which is
misleading. Set the status description based on the actual cause
(lack of vision vs. org policy). The catch/error path keeps the generic
message.

Co-authored-by: SamirSaji <samirsaji13@gmail.com>
@samir-nimbly

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Addressed the feedback:

  • bea3d88 — omitted-reference status now reflects the real cause (missing vision vs. org-policy editor_preview_features=0) instead of always saying the model "does not support images". Error/catch path keeps the generic message.

All unit tests pass locally (vitest, extensions/copilot):

✓ Image > sends image to a vision-capable model when signed out (no Copilot token)
✓ Image > sends image when signed in and editor preview features are enabled
✓ Image > omits image when organization policy disables editor preview features
✓ Image > omits image when the model does not support vision
Test Files  1 passed (1) | Tests  4 passed (4)

…ments-signed-out

# Conflicts:
#	extensions/copilot/src/extension/prompts/node/panel/image.tsx
@samir-nimbly

Copy link
Copy Markdown
Contributor Author

Justin Chen (@justschen) Merge conflict with main is resolved and the branch is now mergeable. Kept the org-policy image gating with a safe default for signed-out/BYOK users (no Copilot token defaults to preview features enabled, so attachments are sent). HistoricalImage and Image both inject IAuthenticationService consistently. Ready for another look whenever you have a chance.

@justschen

Copy link
Copy Markdown
Collaborator

giving this a look this iteration cc Vritant Bhardwaj (@vritant24) since this is BYOK related...

@dmitrivMS
Dmitriy Vasyura (dmitrivMS) enabled auto-merge (squash) July 29, 2026 05:33
@dmitrivMS
Dmitriy Vasyura (dmitrivMS) merged commit e096470 into microsoft:main Jul 29, 2026
29 checks passed
@vs-code-engineering vs-code-engineering Bot added this to the 1.132.0 milestone Jul 29, 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.

Chat image attachments are silently dropped when not signed in to GitHub, even with a configured multimodal provider

6 participants