JuliusBrussee/caveman · error

caveman-code: multiple provider credentials found; set…

Error message

caveman-code: multiple provider credentials found; set CAVE_MODEL to pick one

What it means

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.

Solutions

  1. Set CAVE_MODEL to a provider/model value, e.g. 'openai/gpt-5.5', to pick one
  2. Unset the credentials you do not want used (e.g. unset OPENAI_API_KEY)
  3. Pass the model explicitly in the API call instead of relying on env auto-detection

Example fix

// before
$ export ANTHROPIC_API_KEY=... OPENAI_API_KEY=...
$ cave run
// after
$ export CAVE_MODEL=anthropic/claude-sonnet-4-6
$ cave run
Defensive patterns

Strategy: validation

Validate before calling

const creds = ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "GEMINI_API_KEY", "GOOGLE_API_KEY"]
  .filter((k) => !!process.env[k]);
if (creds.length > 1 && !process.env.CAVE_MODEL) {
  throw new Error(`Multiple provider keys set (${creds.join(",")}); set CAVE_MODEL to disambiguate`);
}

Type guard

null

Try / catch

try {
  await run(task);
} catch (err) {
  if ((err as Error).message.includes("multiple provider credentials")) {
    process.env.CAVE_MODEL ??= "anthropic/claude-sonnet-4-6"; // pick a default explicitly
  } else throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: Dotfiles exporting multiple keys for convenience across tools; CI secrets mounted for several providers; trying a new provider but leaving old keys exported.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/ecfb5c72d7eb1c29. Report an issue: GitHub.

Appendix: source

Thrown at packages/agent/src/code.ts:562

}

function resolveCodingModelID(explicit: string | undefined): string {
  const requested = explicit ?? process.env.CAVE_MODEL;
  if (requested !== undefined && requested !== "") {
    const slash = requested.indexOf("/");
    if (slash <= 0 || slash === requested.length - 1) {
      throw new Error("caveman-code: model must use provider/model format");
    }
    return requested;
  }
  const configured: string[] = [];
  if (process.env.ANTHROPIC_API_KEY) configured.push("anthropic/claude-sonnet-4-6");
  if (process.env.OPENAI_API_KEY) configured.push("openai/gpt-5.5");
  if (process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY) {
    configured.push("google/gemini-2.5-pro");
  }
  if (configured.length !== 1) {
    throw new Error(
      configured.length === 0
        ? "caveman-code: no supported provider credential found; set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY"
        : "caveman-code: multiple provider credentials found; set CAVE_MODEL to pick one",
    );
  }
  return configured[0]!;
}

// ---------------------------------------------------------------------------
// Session
// ---------------------------------------------------------------------------

export type SessionMode = "optimized" | "observe-only";

export interface CodingSessionOptions {
  conversation?: ConversationState;
  cave?: "auto" | "off";
  gatewayURL?: string;

View on GitHub (pinned to 3ee70a1026)