{"record":{"id":"2d5451bd35f0cc4f","repo":"microsoft/vscode","slug":"missing-api-key-for-custom-url-this-urlorreques","errorCode":null,"errorMessage":"Missing API key for custom URL (${this.urlOrRequestMetadata}). Provide the API key using vscode setting `github.copilot.chat.advanced.inlineEdits.xtabProvider.apiKey` or, if in simulations using `--nes-api-key` or `--config-file`","messagePattern":"Missing API key for custom URL \\((.+?)\\)\\. Provide the API key using vscode setting `github\\.copilot\\.chat\\.advanced\\.inlineEdits\\.xtabProvider\\.apiKey` or, if in simulations using `--nes-api-key` or `--config-file`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/copilot/src/extension/xtab/node/xtabEndpoint.ts","lineNumber":92,"sourceCode":"\t\t\t_instantiationService,\n\t\t\t_configService,\n\t\t\t_experimentationService,\n\t\t\t_chatWebSocketService,\n\t\t\t_logService\n\t\t);\n\t}\n\n\toverride get urlOrRequestMetadata(): string {\n\t\treturn this._configService.getConfig(ConfigKey.TeamInternal.InlineEditsXtabProviderUrl) || this._url;\n\t}\n\n\n\tpublic override getExtraHeaders(): Record<string, string> {\n\t\tconst apiKey = this._configService.getConfig(ConfigKey.TeamInternal.InlineEditsXtabProviderApiKey) || this._apiKey;\n\t\tif (!apiKey) {\n\t\t\tconst message = `Missing API key for custom URL (${this.urlOrRequestMetadata}). Provide the API key using vscode setting \\`github.copilot.chat.advanced.inlineEdits.xtabProvider.apiKey\\` or, if in simulations using \\`--nes-api-key\\` or \\`--config-file\\``;\n\t\t\tconsole.error(message);\n\t\t\tthrow new Error(message);\n\t\t}\n\t\treturn {\n\t\t\t'Authorization': `Bearer ${apiKey}`,\n\t\t\t'api-key': apiKey,\n\t\t};\n\t}\n}\n","sourceCodeStart":74,"sourceCodeEnd":100,"githubUrl":"https://github.com/microsoft/vscode/blob/a94b963a32aa9749d69504576791fa29700ae46d/extensions/copilot/src/extension/xtab/node/xtabEndpoint.ts#L74-L100","documentation":"XtabEndpoint is a ChatEndpoint subclass for the cross-tab (xtab) inline-edits provider, a TeamInternal feature pointing at a custom/self-hosted URL. Its getExtraHeaders() must attach a Bearer/api-key Authorization header to every request. The key is resolved from three sources in priority order: the config setting github.copilot.chat.advanced.inlineEdits.xtabProvider.apiKey, then the constructor _apiKey argument, then (for simulations) --nes-api-key/--config-file. If all are empty/falsy, it logs to console.error and throws, because an unauthenticated request to the custom endpoint would fail anyway.","triggerScenarios":"getExtraHeaders() is called during an inline-edit request to the xtab provider when ConfigKey.TeamInternal.InlineEditsXtabProviderApiKey is unset AND the endpoint was constructed with an empty _apiKey AND no simulation flag supplied a key. The check at xtabEndpoint.ts:89 fails and the throw at line 92 fires, embedding the resolved URL (urlOrRequestMetadata) in the message.","commonSituations":"A TeamInternal user enabled the custom xtab provider URL (InlineEditsXtabProviderUrl) but forgot the matching apiKey setting; the setting key was typo'd or scoped to the wrong workspace; a local dev/simulation run omitted --nes-api-key; a config-file override cleared the key; the feature was toggled on by an experiment without the operator provisioning credentials.","solutions":["Set the VS Code setting github.copilot.chat.advanced.inlineEdits.xtabProvider.apiKey to the provider's API key (matching the configured InlineEditsXtabProviderUrl).","If running a simulation, pass --nes-api-key <key> or --config-file <path-to-config-with-key>.","If constructing XtabEndpoint directly, supply a non-empty apiKey as the second constructor argument.","Verify the setting is in the correct scope (user vs workspace) and the key is not being overridden to empty by a higher-priority config source."],"exampleFix":"// before — endpoint constructed without a key and no config setting\nconst endpoint = instantiationService.createInstance(XtabEndpoint, customUrl, '', undefined);\nendpoint.getExtraHeaders(); // throws\n\n// after — pass the key explicitly (or set the config setting)\nconst endpoint = instantiationService.createInstance(XtabEndpoint, customUrl, process.env.XTAB_API_KEY ?? '', undefined);\nendpoint.getExtraHeaders(); // { Authorization: 'Bearer ...', 'api-key': '...' }\n\n// or via settings.json:\n// \"github.copilot.chat.advanced.inlineEdits.xtabProvider.apiKey\": \"<your-key>\"","handlingStrategy":"validation","validationCode":"function resolveXtabApiKey(configService: IConfigurationService, ctorKey: string): string | undefined {\n\treturn configService.getConfig(ConfigKey.TeamInternal.InlineEditsXtabProviderApiKey)\n\t\t|| ctorKey\n\t\t|| process.env.NES_API_KEY\n\t\t|| undefined;\n}\n\n// before triggering an inline edit / calling getExtraHeaders():\nconst key = resolveXtabApiKey(configService, endpointCtorApiKey);\nif (!key) {\n\tthrow new Error('xtab provider selected but no API key configured; set github.copilot.chat.advanced.inlineEdits.xtabProvider.apiKey');\n}","typeGuard":"function hasXtabCredentials(configService: IConfigurationService, ctorKey: string): boolean {\n\treturn Boolean(\n\t\tconfigService.getConfig(ConfigKey.TeamInternal.InlineEditsXtabProviderApiKey)\n\t\t\t|| ctorKey\n\t\t\t|| process.env.NES_API_KEY\n\t);\n}","tryCatchPattern":"try {\n\tconst headers = endpoint.getExtraHeaders();\n\t// attach headers to the fetch request\n} catch (e) {\n\tconst msg = e instanceof Error ? e.message : String(e);\n\tif (msg.startsWith('Missing API key for custom URL')) {\n\t\t// fall back to the default Copilot endpoint OR surface a user-actionable notice;\n\t\t// do NOT retry identically — the config must change first\n\t\tshowWarningMessage('Set github.copilot.chat.advanced.inlineEdits.xtabProvider.apiKey to use the custom xtab provider.');\n\t\treturn;\n\t}\n\tthrow e;\n}","preventionTips":["Always provision InlineEditsXtabProviderApiKey whenever InlineEditsXtabProviderUrl is set — they are a pair.","In simulations, always pass --nes-api-key or a --config-file that includes the key.","Guard with hasXtabCredentials() before enabling the xtab code path so the failure is detected at config time, not mid-request.","Keep the API key in the user settings or a secrets store; never hard-code it in workspace settings that may be committed."],"tags":["copilot","xtab","inline-edits","authentication","api-key","team-internal","configuration"],"analyzedSha":"a94b963a32aa9749d69504576791fa29700ae46d","analyzedAt":"2026-08-12T01:08:56.794Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}