Keep the expected managed settings 404 out of the DevTools console - #331024
Draft
joshspicer wants to merge 1 commit into
Draft
Keep the expected managed settings 404 out of the DevTools console#331024joshspicer wants to merge 1 commit into
joshspicer wants to merge 1 commit into
Conversation
Contributor
📬 CODENOTIFYThe following users are being notified based on files changed in this PR: Robo (@deepak1556)Matched files:
|
Contributor
There was a problem hiding this comment.
Pull request overview
Adds desktop request routing to prevent expected Copilot API failures from cluttering renderer DevTools.
Changes:
- Adds an expected non-success request hint.
- Routes flagged desktop requests through the main process.
- Applies the hint to Copilot account requests.
Show a summary per file
| File | Description |
|---|---|
src/vs/base/parts/request/common/request.ts |
Adds the request hint. |
src/vs/code/electron-main/app.ts |
Registers the main-process request channel. |
src/vs/workbench/services/request/electron-browser/requestService.ts |
Routes flagged requests through IPC. |
src/vs/workbench/services/accounts/browser/defaultAccount.ts |
Flags Copilot account requests. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Suppressed comments (1)
src/vs/workbench/services/request/electron-browser/requestService.ts:51
- This main-process path no longer honors cancellation or
timeoutwhile the response body is being read.RequestChannelbuffers the body only after the mainIRequestService.requestresolves, but the Node request implementation clears its timeout and cancellation listener as soon as response headers arrive; unlike the rendererfetch(...).arrayBuffer()path, a stalled body can therefore hang startup/account resolution indefinitely. Keep the token and timeout active through IPC body buffering before routing these requests here.
if (options.expectNonSuccessStatus) {
return this.logAndRequest(options, () => this.mainProcessRequestClient.request(options, token));
- Files reviewed: 4/4 changed files
- Comments generated: 4
- Review effort level: Balanced
Comment on lines
+58
to
+70
| /** | ||
| * A signal that a non-2xx response is an expected outcome of this request | ||
| * (e.g. `404` meaning "nothing is configured") and therefore must not be | ||
| * reported as a failure to the user. | ||
| * | ||
| * Implementations that issue requests from a browser window can use this to | ||
| * run the request outside of the renderer: Chromium unconditionally logs | ||
| * `Failed to load resource: the server responded with a status of 404` into | ||
| * the Developer Tools console for every `fetch` that resolves with an error | ||
| * status, which is confusing noise for an expected outcome. This may not be | ||
| * supported in all implementations. | ||
| */ | ||
| expectNonSuccessStatus?: boolean; |
Comment on lines
+24
to
+30
| /** | ||
| * Requests that expect a non-2xx response are made from the main process: | ||
| * Chromium logs every `fetch` that resolves with an error status into the | ||
| * Developer Tools console of the window that issued it, which is confusing | ||
| * noise when that status is an expected outcome. | ||
| */ | ||
| private readonly mainProcessRequestClient: RequestChannelClient; |
Comment on lines
+1405
to
+1409
| // Request (for requests that must not run in a window, e.g. because a | ||
| // non-2xx response is expected and Chromium would log it to the | ||
| // Developer Tools console of that window) | ||
| const requestChannel = new RequestChannel(accessor.get(IRequestService)); | ||
| mainProcessElectronServer.registerChannel('request', requestChannel); |
Comment on lines
+1091
to
+1093
| // Non-2xx responses are routine here (e.g. `404` when the account has no | ||
| // managed settings). Keep them out of the window's Developer Tools console | ||
| // by having the request run outside of the renderer. |
Dileep Yavanmandha (dileepyavan)
previously approved these changes
Aug 15, 2026
roblourens
previously approved these changes
Aug 15, 2026
joshspicer
dismissed stale reviews from roblourens and Dileep Yavanmandha (dileepyavan)
via
August 15, 2026 18:52
3d5922e
joshspicer
force-pushed
the
agents/suppress-404-logs-in-dev-tools
branch
from
August 15, 2026 18:52
494a59d to
3d5922e
Compare
roblourens
previously approved these changes
Aug 15, 2026
Dmitriy Vasyura (dmitrivMS)
previously approved these changes
Aug 15, 2026
joshspicer
marked this pull request as draft
August 16, 2026 00:33
The Copilot managed settings endpoint answers `404` when an account simply
has no managed settings. The workbench already treats that as the normal
"no settings" outcome, but Chromium unconditionally logs
Failed to load resource: the server responded with a status of 404
into the Developer Tools console of the window that issued the request.
Nothing on the renderer side suppresses it: `fetch` and `XMLHttpRequest`
both emit it, in the top frame and in iframes, regardless of request
options.
Rewrite the status in the main process before the response reaches the
window — the same `onHeadersReceived` mechanism already used a few lines
above to add CORS headers for the PRSS CDN — and carry the real status in
a response header that the workbench restores before acting on the
response. Only a `404` from that one endpoint is rewritten, so every other
request, and every genuine failure, is reported exactly as before.
The header has to be added to `Access-Control-Expose-Headers` for the
window to read it back, because the request is cross-origin. That list is
extended rather than replaced so the rate-limit headers the workbench
reads off the same response stay visible.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
joshspicer
dismissed stale reviews from Dmitriy Vasyura (dmitrivMS) and roblourens
via
August 16, 2026 00:49
82ffe51
joshspicer
force-pushed
the
agents/suppress-404-logs-in-dev-tools
branch
from
August 16, 2026 00:49
3d5922e to
82ffe51
Compare
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.
Problem
Developer Tools logs this repeatedly, and it looks like a failure:
The
404is not a problem — it is how the endpoint says "this account has no managed settings", andDefaultAccountProvideralready handles it as a normal outcome. The problem is purely that it gets printed.Why it can't be fixed in the renderer
Chromium emits that line from the document's network stack for any response with an error status. Measured via the DevTools
Logdomain (Log.entryAdded, which is exactly what the console renders):fetchXMLHttpRequestfetch+keepalive/cache: 'no-store'There is no request option that suppresses it, and it is not a
console.*call that could be filtered.Fix
Rewrite the status in the main process before the response reaches the window, using the same
session.defaultSession.webRequest.onHeadersReceivedmechanism that already sits a few lines above inapp.ts(used to addAccess-Control-Allow-Originfor the PRSS CDN). The real status travels in a response header that the workbench restores immediately, so every downstream code path still sees the404it sees today — including the retry-next-session logic and thenoSettingshandling.Scope is deliberately tight: only a
404, only fromhttps://api.*/copilot_internal/managed_settings(covering GHES, whose host is alsoapi.-prefixed). Any other status, endpoint or genuine failure is reported exactly as before.One subtlety worth flagging for review: the request is cross-origin, so the marker header is invisible to the window unless it is added to
Access-Control-Expose-Headers. That list is extended, not replaced — replacing it would hide thex-ratelimit-remaining/retry-afterheaders that the rate-limit logic reads off this same response.Verification
Ran the shipped predicate and handler verbatim in Electron (the
.build/electronbinary this repo uses), against a realhttps://api.github.com/copilot_internal/managed_settings?client_id=…URL served by a local HTTPS endpoint that mimics GitHub's response (CORS, its ownaccess-control-expose-headers,x-ratelimit-remaining), with the DevToolsLogdomain attached:So: the noise is gone, the true status is recovered, the rate-limit headers survive, and neighbouring endpoints are unaffected.
Also:
scripts/test.shon the three related suites (53 passing, including new unit tests for the URL predicate and the status restore), plustsc -p src/tsconfig.json,eslint, andvalid-layers-check.Notes
404.findMatchingProviderSessionlists one session once per scope set it matches, so a full-scope GitHub session is listed 3× and the identical request is sent 3× with the same token. That is a real bug but it is not the cause of the printing, so I have left it out of this PR — happy to send it separately.