JuliusBrussee/caveman · error

cave_claude_reasoning_capability_unknown

cave_claude_reasoning_capability_unknown

Error message

cave_claude_reasoning_capability_unknown:${model}

What it means

claudeThinkingCapability classifies models by regex into "adaptive", "manual", or "unknown". When reasoning is enabled and the model is neither adaptive nor manual (capability "unknown"), the runtime refuses to guess how to configure thinking and throws with the model name embedded, so new/renamed Claude models fail loudly until supported.

Solutions

  1. Switch to a supported model, e.g. anthropic/claude-haiku-4-5 or claude-sonnet-4-5.
  2. If reasoning is not required, set the agent's reasoning to "off" (capability check is skipped).
  3. Upgrade the caveman agent package so its capability table recognizes your model.
  4. Fix typos in the configured model name.

Example fix

// before
model: "anthropic/claude-3-5-sonnet-20241022"
// after
model: "anthropic/claude-sonnet-4-5"
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN = [/^claude-(?:haiku-4-5|sonnet-4-5|opus-4-(?:1|5))(?:-\d{8})?$/];
function isKnownClaudeModel(model) {
  return KNOWN.some((re) => re.test(model));
}
if (reasoning !== "off" && !isKnownClaudeModel(model)) {
  throw new Error(`model "${model}" unknown to this runtime; disable reasoning or pick a supported model`);
}

Type guard

function isKnownClaudeModel(v) { return typeof v === "string" && /^claude-(?:haiku-4-5|sonnet-4-5|opus-4-(?:1|5))(?:-\d{8})?$/.test(v); }

Try / catch

try {
  await run(agent, { reasoning: "high" });
} catch (e) {
  if (String(e.message).startsWith("cave_claude_reasoning_capability_unknown:")) {
    console.error(`Unsupported model for reasoning: ${e.message.split(":")[1]}; falling back to reasoning off`);
    return run(agent, { reasoning: "off" });
  }
  throw e;
}

Prevention

When it happens

Trigger: Enabling reasoning on a model string that does not match the known patterns, e.g. "claude-3-5-sonnet", "claude-opus-4-6", a dated snapshot with unexpected format, or a typo like "claude-sonet-4-5".

Common situations: Using an older or newer Claude model added after this runtime's capability table was written; misspelling the model name in CAVE_MODEL or provider.json; snapshot date suffix variants not matching the regex.

Related errors


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

Appendix: source

Thrown at packages/agent/src/claude-runtime.ts:518

  reasoning: AgentDefinition["reasoning"],
  outputMaxTokens: number | undefined,
): Pick<ClaudeSDKOptions, "thinking" | "effort"> {
  if (reasoning === "off") return { thinking: { type: "disabled" } };
  const capability = claudeThinkingCapability(model);
  if (capability === "adaptive") {
    return {
      thinking: { type: "adaptive" },
      effort: claudeEffort(reasoning),
    };
  }
  if (capability === "manual") {
    const budgetTokens = reasoning === "high" ? 8_192 : reasoning === "medium" ? 4_096 : 1_024;
    if (outputMaxTokens !== undefined && outputMaxTokens <= budgetTokens) {
      throw new Error("cave_claude_output_budget_too_small_for_reasoning");
    }
    return { thinking: { type: "enabled", budgetTokens } };
  }
  throw new Error(`cave_claude_reasoning_capability_unknown:${model}`);
}

function claudeThinkingCapability(model: string): "adaptive" | "manual" | "unknown" {
  if (/^claude-(?:haiku-4-5|sonnet-4-5|opus-4-(?:1|5))(?:-\d{8})?$/.test(model)) {
    return "manual";
  }
  if (/^claude-(?:sonnet|opus)-4-[678](?:-\d{8})?$/.test(model) ||
      /^claude-(?:fable|mythos|sonnet|opus)-5(?:-\d+)?$/.test(model)) {
    return "adaptive";
  }
  return "unknown";
}

// Accepts ANY result subtype: error subtypes (error_max_turns, …) carry the
// same provider `usage` a success does, so the receipt can be built from a
// failed run too.
type ClaudeCredentialRegime = "metered" | "subscription" | "unknown";

View on GitHub (pinned to 3ee70a1026)