n8n-io/n8n · error · Error
Invalid credentials for provider "${provider}": ${issues}
Error message
Invalid credentials for provider "${provider}":
${issues} What it means
After resolving the provider, `createModel` passes the credential fields (everything except `id`) through a Zod schema specific to that provider (`PROVIDER_CREDENTIAL_SCHEMAS[provider]`). If validation fails, it formats the Zod issues (path + message per issue) and throws. This catches missing required fields, wrong types, and invalid formats in the credential object.
Source
Thrown at packages/@n8n/agents/src/runtime/model/model-factory.ts:266
credFields = rest;
}
// Host configs (e.g. Instance AI's `{ id, url }` for OpenAI-compatible
// endpoints) spell the base URL as `url`; the provider schemas only know
// `baseURL`, and Zod strips unknown keys, so normalize before validation.
// An EMPTY url means "no custom endpoint" (Instance AI emits `url: ''` for
// the api-key-only config) and must keep the provider default.
if (typeof credFields.url === 'string' && credFields.baseURL === undefined) {
const { url, ...restCreds } = credFields;
credFields = url ? { ...restCreds, baseURL: url } : restCreds;
}
const schema = PROVIDER_CREDENTIAL_SCHEMAS[provider];
const parsed = schema.safeParse(credFields);
if (!parsed.success) {
const issues = parsed.error.issues
.map((i) => ` - ${i.path.join('.')}: ${i.message}`)
.join('\n');
throw new Error(`Invalid credentials for provider "${provider}":\n${issues}`);
}
// Caller-injected transport wins; fall back to the ambient env-proxy resolver.
const resolvedFetch = fetch ?? getProxyFetch();
// Type cast: the registry guarantees the schema and builder are aligned per provider.
return (entry.build as EntryBuilder<typeof provider>)(
parsed.data as never,
modelName,
resolvedFetch,
);
}
/**
* Registry of embedding provider packages and their factory function names.
* Each AI SDK provider follows the same pattern:
* createProvider({ apiKey }).embeddingModel(modelName)
*
* To add a new provider, install its @ai-sdk/* package and add an entry here.View on GitHub (pinned to 5ac6606e81)
Solutions
- Read the formatted issues in the error message — each line names the field path and what Zod requires.
- Provide the missing or corrected credential fields in the config object passed to `createModel`.
- Verify the credential type matches the provider (Anthropic credential for `anthropic/`, Bedrock credential for `aws-bedrock/`, etc.).
- Check the credential resolution pipeline — ensure decryption/lookup actually populates every field the provider schema requires.
Example fix
// before:
createModel({ id: 'aws-bedrock/claude-3-opus', apiKey: 'xxx' });
// Error: Bedrock schema requires region, accessKeyId, secretAccessKey
// after:
createModel({
id: 'aws-bedrock/claude-3-opus',
region: 'us-east-1',
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
}); Defensive patterns
Strategy: validation
Validate before calling
import { PROVIDER_CREDENTIAL_SCHEMAS, type ProviderId } from './provider-credentials';
function validateCredentials(provider: ProviderId, creds: Record<string, unknown>): void {
const schema = PROVIDER_CREDENTIAL_SCHEMAS[provider];
const result = schema.safeParse(creds);
if (!result.success) {
throw new Error(`Credential validation failed for ${provider}: ${result.error.message}`);
}
}
// Before createModel:
validateCredentials(provider, credFields); Try / catch
try {
const model = createModel(config);
} catch (e) {
if (e instanceof Error && e.message.startsWith('Invalid credentials')) {
// Show credential configuration error to user
logger.error('Model credential validation failed', { issues: e.message });
}
throw e;
} Prevention
- Validate credentials with the provider's Zod schema before calling createModel.
- Ensure the credential resolution pipeline (decryption, lookup) populates every required field.
- Match credential type to provider (Anthropic cred for anthropic/, Bedrock cred for aws-bedrock/).
- Run credential validation at config-save time in the UI.
When it happens
Trigger: Passing `createModel({ id: 'anthropic/claude-sonnet-4-5' })` with no API key when the Anthropic schema requires one. Passing `createModel({ id: 'aws-bedrock/claude', apiKey: '...' })` when Bedrock requires `region`, `accessKeyId`, `secretAccessKey`. Passing a malformed URL for `baseURL`.
Common situations: The credential resolution layer (e.g. n8n credential decryption) returned an incomplete or empty object. The wrong credential type was bound to the provider (e.g. OpenAI credential for a Bedrock model). A required field like `apiVersion` for Azure was omitted. Environment variables for the credential were not set.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- LangSmithTelemetry creates its own tracer — do not use .otlp
- Invalid resume payload: ${parseResult.error}
- Episodic memory requires a resolved embedding model before r
- Model ID is required
- Invalid model ID "${rawId}": expected "provider/model-name"
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/8ffb375cda98d489.
Report an issue: GitHub.