vercel/ai · error · TypeError
Invalid auth: expected an authentication mode or a flat reco
Error message
Invalid auth: expected an authentication mode or a flat record with string values.
What it means
isHarnessAuthenticationEnvironment accepts either a recognized authentication mode or a flat record whose values are all strings. An array, or an object with non-string values (numbers, booleans, nested objects), is rejected with this TypeError because auth environment variables must be flat string-to-string maps.
Source
Thrown at packages/harness/src/utils/authentication-environment.ts:14
import type { HarnessV1AuthenticationEnvironment } from '../v1/harness-authentication';
export function isHarnessAuthenticationEnvironment(
value: unknown,
): value is HarnessV1AuthenticationEnvironment {
if (value == null || typeof value !== 'object') {
return false;
}
if (
Array.isArray(value) ||
Object.values(value).some(entry => typeof entry !== 'string')
) {
throw new TypeError(
'Invalid auth: expected an authentication mode or a flat record with string values.',
);
}
return true;
}
View on GitHub (pinned to 69428b1f8b)
Solutions
- Convert every value to a string: PORT: '8080', DEBUG: 'true'.
- Flatten nested objects into flat string entries (or pass a supported authentication mode instead).
- If passing an array by mistake, convert it to an object: Object.fromEntries(pairs).
Example fix
// before
const auth = { apiKey: 'sk-...', retries: 3 };
// after
const auth = { apiKey: 'sk-...', retries: String(3) }; Defensive patterns
Strategy: validation
Validate before calling
const valid = auth != null && !Array.isArray(auth) && Object.values(auth).every(v => typeof v === 'string');
Type guard
function isFlatStringRecord(v: unknown): v is Record<string, string> { return typeof v === 'object' && v !== null && !Array.isArray(v) && Object.values(v).every(x => typeof x === 'string'); } Try / catch
try { createHarness({ auth }); } catch (e) { if (e instanceof TypeError && e.message.includes('Invalid auth')) { auth = Object.fromEntries(Object.entries(auth).map(([k, v]) => [k, String(v)])); createHarness({ auth }); } else throw e; } Prevention
- Type auth as Record<string, string> so non-string values fail at compile time
- Stringify env values when loading from JSON config
- Never pass arrays or nested objects as auth environment
When it happens
Trigger: Passing auth as an array of pairs, a nested object ({ credentials: { token } }), or values like { PORT: 8080 } / { DEBUG: true } to the harness authentication option.
Common situations: Reusing a process.env-like object typed loosely; loading JSON config where numbers/booleans aren't stringified; accidentally passing an env array from another API.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- params.values must be an array of strings
- ACP runtime environment key ${JSON.stringify(key)} cannot be
- ACP runtime environment key ${JSON.stringify(key)} cannot be
- ACP runtime environment key ${JSON.stringify(key)} cannot be
- ACP environment variable name is invalid: ${JSON.stringify(k
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/a6618d24907d338b.
Report an issue: GitHub.