vercel/ai · error · InvalidArgumentError
Both apiKey and tokenProvider were provided. Please use only
Error message
Both apiKey and tokenProvider were provided. Please use only one authentication method.
What it means
createAzure validates that exactly one auth mechanism is configured. Passing both options.apiKey and options.tokenProvider is ambiguous, so it throws InvalidArgumentError immediately at provider creation.
Source
Thrown at packages/azure/src/azure-openai-provider.ts:173
useDeploymentBasedUrls?: boolean;
}
function isAzureOpenAIBaseURL(baseURL: string | undefined) {
return (
baseURL == null || new URL(baseURL).hostname.endsWith('.openai.azure.com')
);
}
/**
* Create an Azure OpenAI provider instance.
*/
export function createAzure(
options: AzureOpenAIProviderSettings = {},
): AzureOpenAIProvider {
const tokenProvider = options.tokenProvider;
if (options.apiKey && tokenProvider) {
throw new InvalidArgumentError({
argument: 'apiKey/tokenProvider',
message:
'Both apiKey and tokenProvider were provided. Please use only one authentication method.',
});
}
const getHeaders = () => {
const authHeaders = tokenProvider
? {}
: {
'api-key': loadApiKey({
apiKey: options.apiKey,
environmentVariableName: 'AZURE_API_KEY',
description: 'Azure OpenAI',
}),
};
return withUserAgentSuffix(View on GitHub (pinned to 69428b1f8b)
Solutions
- Remove options.apiKey and keep tokenProvider for Entra ID / AAD auth.
- Or remove tokenProvider and keep apiKey for key-based auth.
- Make the choice conditional in code so only one is ever passed.
Example fix
// before
const azure = createAzure({ apiKey: process.env.AZURE_API_KEY, tokenProvider: getAccessToken });
// after
const azure = createAzure({ tokenProvider: getAccessToken }); // or { apiKey: process.env.AZURE_API_KEY } Defensive patterns
Strategy: validation
Validate before calling
const settings = { apiKey: process.env.AZURE_API_KEY, tokenProvider };
if (settings.apiKey && settings.tokenProvider) {
throw new Error('Configure either apiKey or tokenProvider for Azure, not both');
} Try / catch
try {
const azure = createAzure(settings);
} catch (e) {
if (e instanceof InvalidArgumentError && e.message.includes('tokenProvider')) {
// sanitize config and rebuild
}
} Prevention
- Build auth settings from a single source and pick one mechanism explicitly.
- Delete legacy API key env vars when switching to token-based auth.
- Never spread two config objects that may both set credentials.
When it happens
Trigger: Calling createAzure({ apiKey: '...', tokenProvider }) — or the equivalent createAzureOpenAI — with both an API key and a token provider callback.
Common situations: Migrating from API-key auth to Entra ID token auth but leaving the old AZURE_API_KEY env var wired in; merging default config objects where both fields are set.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Both apiKey and authToken were provided. Please use only one
- AI Gateway authentication was selected, but neither AI_GATEW
- ACP authentication method ${JSON.stringify(methodId)} is not
- [cursor] auth: ${JSON.stringify(auth)} cannot configure Curs
- Invalid argument for parameter requests: request IDs must be
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/67c2f1b1ba9cf4ac.
Report an issue: GitHub.