{"record":{"id":"bd76ca3bd9b098df","repo":"eyaltoledano/claude-task-master","slug":"unknown-provider-providername-for-api-key-res","errorCode":null,"errorMessage":"Unknown provider '${providerName}' for API key resolution.","messagePattern":"Unknown provider '(.+?)' for API key resolution\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/modules/ai-services-unified.js","lineNumber":385,"sourceCode":"\t\tprojectId,\n\t\tlocation,\n\t\t...(credentials && { credentials })\n\t};\n}\n\n/**\n * Internal helper to resolve the API key for a given provider.\n * @param {string} providerName - The name of the provider (lowercase).\n * @param {object|null} session - Optional MCP session object.\n * @param {string|null} projectRoot - Optional project root path for .env fallback.\n * @returns {string|null} The API key or null if not found/needed.\n * @throws {Error} If a required API key is missing.\n */\nfunction _resolveApiKey(providerName, session, projectRoot = null) {\n\t// Get provider instance\n\tconst provider = _getProvider(providerName);\n\tif (!provider) {\n\t\tthrow new Error(\n\t\t\t`Unknown provider '${providerName}' for API key resolution.`\n\t\t);\n\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}","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/scripts/modules/ai-services-unified.js#L367-L403","documentation":"_resolveApiKey in the unified AI services layer looks up a provider instance by name before resolving its API key. If the name does not match any registered provider, it throws immediately. This guards against silently continuing with an unrecognized provider string from config or CLI flags.","triggerScenarios":"Calling an AI service (or _unifiedServiceRunner) with provider='openai ' (typo/whitespace), 'gpt4', 'anthropic-' or any name not returned by _getProvider — often from a misspelled --provider flag or a stale config entry.","commonSituations":"Typos in CLI/model config, renaming between supported providers across versions (old names no longer registered), casing mismatches, or trailing whitespace from env/config parsing.","solutions":["Use an exact, supported provider name (e.g. 'openai', 'anthropic', 'google', 'perplexity', 'xai', 'ollama', 'openrouter').","Check `task-master models` list/available providers to see valid names.","Trim whitespace and fix casing in the config/flag supplying the provider name.","If upgrading from an older version, migrate any renamed provider IDs in your config."],"exampleFix":"// before\nawait generateTextService({ providerName: 'OpenAI ', ... }); // unknown provider\n// after\nawait generateTextService({ providerName: 'openai', ... }); // exact registered name","handlingStrategy":"validation","validationCode":"const SUPPORTED = ['openai','anthropic','google','perplexity','xai','ollama','openrouter'];\nif (!SUPPORTED.includes(String(providerName).trim())) {\n  throw new Error(`Unsupported provider \"${providerName}\". Valid: ${SUPPORTED.join(', ')}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const result = await generateTextService({ providerName, ... });\n} catch (e) {\n  if (/Unknown provider/.test(e.message)) {\n    console.error(`Provider \"${providerName}\" not recognized; run 'task-master models' to list valid providers.`);\n  } else throw e;\n}","preventionTips":["Validate provider names against the known list at CLI/config parse time.","Trim and lowercase provider strings from config/env.","After upgrading, migrate renamed provider IDs."],"tags":["configuration","ai-providers","validation"],"backgroundTag":"unknown-provider","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}