{"record":{"id":"ecfb5c72d7eb1c29","repo":"JuliusBrussee/caveman","slug":"caveman-code-multiple-provider-credentials-found","errorCode":null,"errorMessage":"caveman-code: multiple provider credentials found; set CAVE_MODEL to pick one","messagePattern":"caveman-code: multiple provider credentials found; set CAVE_MODEL to pick one","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/code.ts","lineNumber":562,"sourceCode":"}\n\nfunction resolveCodingModelID(explicit: string | undefined): string {\n  const requested = explicit ?? process.env.CAVE_MODEL;\n  if (requested !== undefined && requested !== \"\") {\n    const slash = requested.indexOf(\"/\");\n    if (slash <= 0 || slash === requested.length - 1) {\n      throw new Error(\"caveman-code: model must use provider/model format\");\n    }\n    return requested;\n  }\n  const configured: string[] = [];\n  if (process.env.ANTHROPIC_API_KEY) configured.push(\"anthropic/claude-sonnet-4-6\");\n  if (process.env.OPENAI_API_KEY) configured.push(\"openai/gpt-5.5\");\n  if (process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY) {\n    configured.push(\"google/gemini-2.5-pro\");\n  }\n  if (configured.length !== 1) {\n    throw new Error(\n      configured.length === 0\n        ? \"caveman-code: no supported provider credential found; set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY\"\n        : \"caveman-code: multiple provider credentials found; set CAVE_MODEL to pick one\",\n    );\n  }\n  return configured[0]!;\n}\n\n// ---------------------------------------------------------------------------\n// Session\n// ---------------------------------------------------------------------------\n\nexport type SessionMode = \"optimized\" | \"observe-only\";\n\nexport interface CodingSessionOptions {\n  conversation?: ConversationState;\n  cave?: \"auto\" | \"off\";\n  gatewayURL?: string;","sourceCodeStart":544,"sourceCodeEnd":580,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/code.ts#L544-L580","documentation":"When no model is explicitly chosen and more than one provider credential env var is set, resolveCodingModelID cannot determine which provider to use and throws, asking the user to disambiguate with CAVE_MODEL.","triggerScenarios":"Having two or more of ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY/GOOGLE_API_KEY set simultaneously while neither the model option nor CAVE_MODEL is provided.","commonSituations":"Dotfiles exporting multiple keys for convenience across tools; CI secrets mounted for several providers; trying a new provider but leaving old keys exported.","solutions":["Set CAVE_MODEL to a provider/model value, e.g. 'openai/gpt-5.5', to pick one","Unset the credentials you do not want used (e.g. unset OPENAI_API_KEY)","Pass the model explicitly in the API call instead of relying on env auto-detection"],"exampleFix":"// before\n$ export ANTHROPIC_API_KEY=... OPENAI_API_KEY=...\n$ cave run\n// after\n$ export CAVE_MODEL=anthropic/claude-sonnet-4-6\n$ cave run","handlingStrategy":"validation","validationCode":"const creds = [\"ANTHROPIC_API_KEY\", \"OPENAI_API_KEY\", \"GEMINI_API_KEY\", \"GOOGLE_API_KEY\"]\n  .filter((k) => !!process.env[k]);\nif (creds.length > 1 && !process.env.CAVE_MODEL) {\n  throw new Error(`Multiple provider keys set (${creds.join(\",\")}); set CAVE_MODEL to disambiguate`);\n}","typeGuard":"null","tryCatchPattern":"try {\n  await run(task);\n} catch (err) {\n  if ((err as Error).message.includes(\"multiple provider credentials\")) {\n    process.env.CAVE_MODEL ??= \"anthropic/claude-sonnet-4-6\"; // pick a default explicitly\n  } else throw err;\n}","preventionTips":["Set CAVE_MODEL whenever more than one provider key is exported","Unset unused provider keys in dotfiles/CI to keep auto-detection unambiguous","Pass the model option explicitly in programmatic use instead of relying on env detection"],"tags":["config","env","ambiguity"],"backgroundTag":"conflicting-config-options","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}