{"record":{"id":"88cce697c87ea53c","repo":"JuliusBrussee/caveman","slug":"cave-claude-model-required","errorCode":"cave_claude_model_required","errorMessage":"cave_claude_model_required","messagePattern":"cave_claude_model_required","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/claude-runtime.ts","lineNumber":468,"sourceCode":"  if (/[:\\r\\n]/.test(name) || /[\\r\\n]/.test(value)) {\n    throw new Error(\"cave_claude_header_invalid\");\n  }\n  const target = name.toLowerCase();\n  const kept = (raw ?? \"\").split(/\\r\\n|\\n|\\r/).filter((line) => {\n    if (!line.trim()) return false;\n    const colon = line.indexOf(\":\");\n    return (colon < 0 ? line : line.slice(0, colon)).trim().toLowerCase() !== target;\n  });\n  kept.push(`${name}: ${value}`);\n  return kept.join(\"\\n\");\n}\n\nfunction resolveClaudeModel(definition: AgentDefinition, rootDir: string): string {\n  const configured = typeof definition.model === \"string\"\n    ? definition.model\n    : process.env.CAVE_MODEL ?? localModel(rootDir) ??\n      (process.env.ANTHROPIC_API_KEY ? \"anthropic/claude-haiku-4-5\" : undefined);\n  if (configured === undefined) throw new Error(\"cave_claude_model_required\");\n  const separator = configured.indexOf(\"/\");\n  if (separator < 1 || configured.slice(0, separator) !== \"anthropic\") {\n    throw new Error(\"cave_claude_provider_unsupported\");\n  }\n  return normalizeClaudeModel(configured.slice(separator + 1));\n}\n\nfunction localModel(rootDir: string): string | undefined {\n  try {\n    const parsed = JSON.parse(readFileSync(resolve(rootDir, \".caveman/provider.json\"), \"utf8\")) as {\n      model?: unknown;\n    };\n    return typeof parsed.model === \"string\" ? parsed.model : undefined;\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return undefined;\n    throw new Error(\"caveman agent: invalid .caveman/provider.json\");\n  }\n}","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/claude-runtime.ts#L450-L486","documentation":"resolveClaudeModel must produce a model string; it consults definition.model, the CAVE_MODEL env var, the project-local model config, and finally defaults to anthropic/claude-haiku-4-5 only when ANTHROPIC_API_KEY is set. If every source is empty, it throws this error.","triggerScenarios":"Calling runClaudeAgent with a definition lacking a model, no CAVE_MODEL set, no local model config file, and no ANTHROPIC_API_KEY in the environment.","commonSituations":"Fresh checkout without .env loaded; CI environment missing CAVE_MODEL/ANTHROPIC_API_KEY; running outside the project root so the local model config file isn't found.","solutions":["Set definition.model to an anthropic-prefixed model, e.g. \"anthropic/claude-haiku-4-5\"","Export CAVE_MODEL=anthropic/claude-sonnet-4-5 (or add the model to the local config in rootDir)","Set ANTHROPIC_API_KEY so the haiku-4-5 default applies"],"exampleFix":"// before\nawait runClaudeAgent({ definition, input }); // no model anywhere\n// after\nawait runClaudeAgent({ definition: { ...definition, model: \"anthropic/claude-haiku-4-5\" }, input });","handlingStrategy":"validation","validationCode":"if (!definition.model && !process.env.CAVE_MODEL && !process.env.ANTHROPIC_API_KEY) throw new Error(\"Set definition.model, CAVE_MODEL, or ANTHROPIC_API_KEY before running\");","typeGuard":null,"tryCatchPattern":"try { await runClaudeAgent(opts); } catch (e) { if (e.message === \"cave_claude_model_required\") { opts.definition = { ...opts.definition, model: \"anthropic/claude-haiku-4-5\" }; return runClaudeAgent(opts); } throw e; }","preventionTips":["Always set a model on agent definitions targeting Claude","Load .env before invoking the runtime","In CI, export CAVE_MODEL explicitly"],"tags":["model","configuration","env","claude-runtime"],"backgroundTag":"missing-config-value","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"}