{"record":{"id":"8c83dcbb414b502a","repo":"eyaltoledano/claude-task-master","slug":"required-api-key-envvarname-for-provider-pro","errorCode":null,"errorMessage":"Required API key ${envVarName} for provider '${providerName}' is not set in environment, session, or .env file.","messagePattern":"Required API key (.+?) for provider '(.+?)' is not set in environment, session, or \\.env file\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/modules/ai-services-unified.js","lineNumber":406,"sourceCode":"\t}\n\n\t// All providers must implement getRequiredApiKeyName()\n\tconst envVarName = provider.getRequiredApiKeyName();\n\n\t// If envVarName is null (like for MCP), return null directly\n\tif (envVarName === null) {\n\t\treturn null;\n\t}\n\n\tconst apiKey = resolveEnvVariable(envVarName, session, projectRoot);\n\n\t// Special handling for providers that can use alternative auth or no API key\n\tif (!provider.isRequiredApiKey()) {\n\t\treturn apiKey || null;\n\t}\n\n\tif (!apiKey) {\n\t\tthrow new Error(\n\t\t\t`Required API key ${envVarName} for provider '${providerName}' is not set in environment, session, or .env file.`\n\t\t);\n\t}\n\treturn apiKey;\n}\n\n/**\n * Internal helper to attempt a provider-specific AI API call with retries.\n *\n * @param {function} providerApiFn - The specific provider function to call (e.g., generateAnthropicText).\n * @param {object} callParams - Parameters object for the provider function.\n * @param {string} providerName - Name of the provider (for logging).\n * @param {string} modelId - Specific model ID (for logging).\n * @param {string} attemptRole - The role being attempted (for logging).\n * @returns {Promise<object>} The result from the successful API call.\n * @throws {Error} If the call fails after all retries.\n */\nasync function _attemptProviderCallWithRetries(","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/scripts/modules/ai-services-unified.js#L388-L424","documentation":"_resolveApiKey validates that providers requiring an API key actually have one. It searches the explicit apiKey argument, the session, and the .env file/environment for the provider's required env var (from getRequiredApiKeyName()). If nothing yields a key, it throws with the exact env var name so the developer knows what to set.","triggerScenarios":"Calling generateTextService/generateObjectService/stream* for a provider whose required key (e.g. ANTHROPIC_API_KEY, OPENAI_API_KEY) is absent from the environment, the mcpSession/global session, and the project's .env file, while the provider's isRequiredApiKey() is true.","commonSituations":"Fresh clone without .env set up, CI pipelines missing secrets, keys defined in a different .env location than the project root, key set under the wrong variable name, or using a key-requiring provider (e.g. Anthropic) where a keyless one (Ollama) was intended.","solutions":["Set the named env var (printed in the error, e.g. ANTHROPIC_API_KEY) in your shell or in the project root .env file.","Pass the key explicitly via the service's apiKey parameter if you manage keys yourself.","In CI, add the secret to the pipeline environment.","Switch to a provider that doesn't require an API key (e.g. Ollama) if you have no key.","Verify the variable name matches exactly what the provider's getRequiredApiKeyName() returns — no aliases."],"exampleFix":"// before\n# .env\nANTHROPIC_KEY=sk-... // wrong name, still throws\n// after\n# .env (project root)\nANTHROPIC_API_KEY=sk-ant-...","handlingStrategy":"validation","validationCode":"// fail fast before calling the service\nconst key = process.env.ANTHROPIC_API_KEY; // use the provider's required var name\nif (!key) {\n  throw new Error('Set ANTHROPIC_API_KEY in your environment or project .env before running AI services.');\n}","typeGuard":"function hasApiKey(envVarName) {\n  return typeof process.env[envVarName] === 'string' && process.env[envVarName].length > 0;\n}","tryCatchPattern":"try {\n  await generateTextService({ providerName: 'anthropic', prompt });\n} catch (e) {\n  if (/Required API key .* is not set/.test(e.message)) {\n    console.error('Missing API key: copy .env.example to .env and fill in the listed key.');\n    process.exitCode = 1;\n  } else throw e;\n}","preventionTips":["Copy .env.example to .env during project setup and commit .env.example (never .env).","In CI, declare all required provider secrets explicitly.","Check the exact env var name in the error message — aliases are not accepted.","For local dev without keys, switch to a keyless provider like Ollama."],"tags":["configuration","api-key","environment","ai-providers"],"backgroundTag":"missing-env-var","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}