microsoft/vscode · error · Error

Missing API key for custom URL (${this.urlOrRequestMetadata}

Error 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`

What it means

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.

Source

Thrown at extensions/copilot/src/extension/xtab/node/xtabEndpoint.ts:92

			_instantiationService,
			_configService,
			_experimentationService,
			_chatWebSocketService,
			_logService
		);
	}

	override get urlOrRequestMetadata(): string {
		return this._configService.getConfig(ConfigKey.TeamInternal.InlineEditsXtabProviderUrl) || this._url;
	}


	public override getExtraHeaders(): Record<string, string> {
		const apiKey = this._configService.getConfig(ConfigKey.TeamInternal.InlineEditsXtabProviderApiKey) || this._apiKey;
		if (!apiKey) {
			const 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\``;
			console.error(message);
			throw new Error(message);
		}
		return {
			'Authorization': `Bearer ${apiKey}`,
			'api-key': apiKey,
		};
	}
}

View on GitHub (pinned to a94b963a32)

Solutions

  1. Set the VS Code setting github.copilot.chat.advanced.inlineEdits.xtabProvider.apiKey to the provider's API key (matching the configured InlineEditsXtabProviderUrl).
  2. If running a simulation, pass --nes-api-key <key> or --config-file <path-to-config-with-key>.
  3. If constructing XtabEndpoint directly, supply a non-empty apiKey as the second constructor argument.
  4. 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.

Example fix

// before — endpoint constructed without a key and no config setting
const endpoint = instantiationService.createInstance(XtabEndpoint, customUrl, '', undefined);
endpoint.getExtraHeaders(); // throws

// after — pass the key explicitly (or set the config setting)
const endpoint = instantiationService.createInstance(XtabEndpoint, customUrl, process.env.XTAB_API_KEY ?? '', undefined);
endpoint.getExtraHeaders(); // { Authorization: 'Bearer ...', 'api-key': '...' }

// or via settings.json:
// "github.copilot.chat.advanced.inlineEdits.xtabProvider.apiKey": "<your-key>"
Defensive patterns

Strategy: validation

Validate before calling

function resolveXtabApiKey(configService: IConfigurationService, ctorKey: string): string | undefined {
	return configService.getConfig(ConfigKey.TeamInternal.InlineEditsXtabProviderApiKey)
		|| ctorKey
		|| process.env.NES_API_KEY
		|| undefined;
}

// before triggering an inline edit / calling getExtraHeaders():
const key = resolveXtabApiKey(configService, endpointCtorApiKey);
if (!key) {
	throw new Error('xtab provider selected but no API key configured; set github.copilot.chat.advanced.inlineEdits.xtabProvider.apiKey');
}

Type guard

function hasXtabCredentials(configService: IConfigurationService, ctorKey: string): boolean {
	return Boolean(
		configService.getConfig(ConfigKey.TeamInternal.InlineEditsXtabProviderApiKey)
			|| ctorKey
			|| process.env.NES_API_KEY
	);
}

Try / catch

try {
	const headers = endpoint.getExtraHeaders();
	// attach headers to the fetch request
} catch (e) {
	const msg = e instanceof Error ? e.message : String(e);
	if (msg.startsWith('Missing API key for custom URL')) {
		// fall back to the default Copilot endpoint OR surface a user-actionable notice;
		// do NOT retry identically — the config must change first
		showWarningMessage('Set github.copilot.chat.advanced.inlineEdits.xtabProvider.apiKey to use the custom xtab provider.');
		return;
	}
	throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of microsoft/vscode@a94b963a32 (2026-08-12). Data as JSON: /api/errors/2d5451bd35f0cc4f. Report an issue: GitHub.