{"record":{"id":"2e421dff014fac44","repo":"eyaltoledano/claude-task-master","slug":"authentication-error","errorCode":"AUTHENTICATION_ERROR","errorMessage":"API key is required","messagePattern":"API key is required","errorType":"error_code","errorClass":"TaskMasterError","httpStatus":null,"severity":"critical","filePath":"packages/tm-core/src/modules/ai/providers/base-provider.ts","lineNumber":80,"sourceCode":" * Prepared request after preprocessing\n */\ninterface PreparedRequest {\n\tprompt: string;\n\toptions: AIOptions;\n\tmetadata: Record<string, any>;\n}\n\n/**\n * Abstract base provider implementing Template Method pattern\n * Provides common error handling, retry logic, and validation\n */\nexport abstract class BaseProvider implements IAIProvider {\n\tprotected readonly apiKey: string;\n\tprotected model: string;\n\n\tconstructor(config: BaseProviderConfig) {\n\t\tif (!config.apiKey) {\n\t\t\tthrow new TaskMasterError(\n\t\t\t\t'API key is required',\n\t\t\t\tERROR_CODES.AUTHENTICATION_ERROR\n\t\t\t);\n\t\t}\n\t\tthis.apiKey = config.apiKey;\n\t\tthis.model = config.model || this.getDefaultModel();\n\t}\n\n\t/**\n\t * Template method for generating completions\n\t * Handles validation, retries, and error handling\n\t */\n\tasync generateCompletion(\n\t\tprompt: string,\n\t\toptions?: AIOptions\n\t): Promise<AIResponse> {\n\t\t// Validate input\n\t\tconst validation = this.validateInput(prompt, options);","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/packages/tm-core/src/modules/ai/providers/base-provider.ts#L62-L98","documentation":"BaseProvider's constructor requires a non-empty apiKey in the BaseProviderConfig; without credentials no provider can authenticate, so it throws a TaskMasterError with code AUTHENTICATION_ERROR immediately at instantiation time rather than failing on the first API call.","triggerScenarios":"new ZAIProvider({ apiKey: undefined }) when the env var (e.g. ZAI_API_KEY / OPENAI_API_KEY / ANTHROPIC_API_KEY) is unset or empty; config files loaded from the wrong directory; dotenv not initialized before constructing the provider.","commonSituations":"Missing .env file in CI or Docker (secrets not mounted); renamed env variables after a version change; typos in the env var name; using a wrong-provider key that ended up undefined after key-per-provider lookup.","solutions":["Set the provider's API key env var (or pass apiKey in the provider config)","Ensure dotenv/config is loaded before constructing the provider","Verify the key is non-empty: console.log(Boolean(process.env.MY_API_KEY)) — then restart the shell/CI after adding the secret"],"exampleFix":"// before\nconst provider = new ZAIProvider({ apiKey: process.env.ZAI_API_KEY });\n// after\nconst apiKey = process.env.ZAI_API_KEY;\nif (!apiKey) throw new Error('Set ZAI_API_KEY in your environment');\nconst provider = new ZAIProvider({ apiKey });","handlingStrategy":"validation","validationCode":"function requireApiKey(envVar: string): string {\n  const key = process.env[envVar];\n  if (!key) throw new Error(`Missing ${envVar}; set it in your environment or .env`);\n  return key;\n}\nconst provider = new ZAIProvider({ apiKey: requireApiKey('ZAI_API_KEY') });","typeGuard":"function hasApiKey(config: BaseProviderConfig): config is BaseProviderConfig & { apiKey: string } {\n  return typeof config.apiKey === 'string' && config.apiKey.length > 0;\n}","tryCatchPattern":"try {\n  provider = new ZAIProvider({ apiKey });\n} catch (err) {\n  if (err instanceof TaskMasterError && err.code === ERROR_CODES.AUTHENTICATION_ERROR) {\n    throw new Error('Provider not configured: API key missing. Check your .env / CI secrets.');\n  }\n  throw err;\n}","preventionTips":["Load dotenv/secrets before constructing providers","Name env vars per provider and check them at startup with a fail-fast config validator","Mount secrets in CI/Docker and verify with a startup smoke test","Never hardcode keys; always read from env or a secret manager"],"tags":["ai-provider","authentication","missing-credentials","configuration"],"backgroundTag":"missing-api-key","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}