{"record":{"id":"c51835c3d8463558","repo":"vercel/ai","slug":"description-api-key-must-be-a-string-c51835","errorCode":null,"errorMessage":"${description} API key must be a string.","messagePattern":"(.+?) API key must be a string\\.","errorType":"exception","errorClass":"LoadAPIKeyError","httpStatus":null,"severity":"error","filePath":"packages/provider-utils/src/load-api-key.ts","lineNumber":19,"sourceCode":"import { LoadAPIKeyError } from '@ai-sdk/provider';\n\nexport function loadApiKey({\n  apiKey,\n  environmentVariableName,\n  apiKeyParameterName = 'apiKey',\n  description,\n}: {\n  apiKey: string | undefined;\n  environmentVariableName: string;\n  apiKeyParameterName?: string;\n  description: string;\n}): string {\n  if (typeof apiKey === 'string') {\n    return apiKey;\n  }\n\n  if (apiKey != null) {\n    throw new LoadAPIKeyError({\n      message: `${description} API key must be a string.`,\n    });\n  }\n\n  if (typeof process === 'undefined') {\n    throw new LoadAPIKeyError({\n      message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter. Environment variables are not supported in this environment.`,\n    });\n  }\n\n  apiKey = process.env[environmentVariableName];\n\n  if (apiKey == null) {\n    throw new LoadAPIKeyError({\n      message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter or the ${environmentVariableName} environment variable.`,\n    });\n  }\n","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/provider-utils/src/load-api-key.ts#L1-L37","documentation":"loadApiKey validates the API key passed to a provider factory. If you supplied a value that is neither a string nor null/undefined (e.g. a number, object, or boolean), it throws LoadAPIKeyError with this message. It prevents silently sending an invalid credential type in request headers.","triggerScenarios":"Calling a provider factory like createOpenAI({ apiKey: 12345 }) or createAnthropic({ apiKey: { key: '...' } }) with a non-string, non-nullish apiKey option.","commonSituations":"Reading the key from config with the wrong type (YAML/JSON numbers), passing an API-key wrapper object, using `apiKey: false` or a placeholder constant, template/config tooling injecting wrong types.","solutions":["Pass the API key as a plain string: apiKey: 'sk-...'","Coerce env/config values to string before passing (String(value) after null check)","If you have no key, omit the option so loadApiKey falls back to the environment variable","Check config parsing (dotenv, YAML, CLI args) for type coercion issues"],"exampleFix":"// before\nconst openai = createOpenAI({ apiKey: 12345 });\n// after\nconst openai = createOpenAI({ apiKey: process.env.OPENAI_API_KEY });","handlingStrategy":"validation","validationCode":"const apiKey = typeof cfg.apiKey === 'string' ? cfg.apiKey : process.env.OPENAI_API_KEY;\nif (typeof apiKey !== 'string') throw new Error('apiKey must be a string');\nconst provider = createOpenAI({ apiKey });","typeGuard":"function isApiKey(value: unknown): value is string {\n  return typeof value === 'string';\n}","tryCatchPattern":"try {\n  const provider = createOpenAI({ apiKey: config.apiKey });\n} catch (error) {\n  if (LoadAPIKeyError.isInstance?.(error) || /API key must be a string/.test(String(error.message))) {\n    throw new Error('Config error: apiKey must be a string, got ' + typeof config.apiKey);\n  }\n  throw error;\n}","preventionTips":["Type your config with `apiKey: string` so TypeScript rejects non-string values","Validate config at startup with a schema (zod) before creating providers","Avoid placeholder values like false, 0, or objects for apiKey"],"tags":["configuration","api-key","validation"],"backgroundTag":"invalid-api-key","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}