{"record":{"id":"e6d32809829a20f6","repo":"JuliusBrussee/caveman","slug":"caveman-agent-invalid-caveman-provider-json-e6d328","errorCode":null,"errorMessage":"caveman agent: invalid .caveman/provider.json","messagePattern":"caveman agent: invalid \\.caveman/provider\\.json","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/agent/src/runtime.ts","lineNumber":3274,"sourceCode":"    throw new Error(\n      configured.length === 0\n        ? \"caveman agent: no supported provider credential found\"\n        : \"caveman agent: multiple provider credentials found; set CAVE_MODEL once\",\n    );\n  }\n  const [provider, id] = configured[0]!;\n  const model = models.getModel(provider, id);\n  if (!model) throw new Error(`caveman agent: baseline model unavailable: ${provider}/${id}`);\n  return model;\n}\n\nfunction localProviderModel(rootDir: string): string | undefined {\n  try {\n    const parsed = JSON.parse(readFileSync(resolve(rootDir, \".caveman/provider.json\"), \"utf8\")) as { model?: unknown };\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}\n\n/**\n * Point a model at the gateway when the gateway speaks its dialect.\n *\n * The three routes below are the only ones the Caveman gateway proxies. Every\n * other provider Pi can reach (xai, groq, bedrock, openrouter, …) keeps its own\n * base URL, and `routed: false` is what tells the caller this request is\n * third-party traffic: no account key, no telemetry headers, no `optimized`.\n */\nfunction routeModelThroughCave(\n  model: Model<Api>,\n  gatewayURL: string,\n): { model: Model<Api>; routed: boolean } {\n  const prefix: Record<string, string> = {\n    anthropic: \"anthropic\",\n    // Pi provider clients append endpoint paths relative to these versioned","sourceCodeStart":3256,"sourceCodeEnd":3292,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/packages/agent/src/runtime.ts#L3256-L3292","documentation":"`localProviderModel` reads `.caveman/provider.json` to pick up a locally pinned model. If parsing the file throws for any reason other than ENOENT (missing file), it rethrows as `caveman agent: invalid .caveman/provider.json`. A missing file is tolerated (returns undefined), but a present, unreadable, or malformed file fails the run.","triggerScenarios":"`.caveman/provider.json` exists but contains invalid JSON (trailing comma, comments, truncation), is a directory, or is unreadable due to permissions — any read/parse error whose code is not ENOENT.","commonSituations":"Hand-editing the file and leaving broken JSON; a failed/crashed write leaving a truncated file; creating `.caveman/provider.json` as a directory by mistake; permission changes after copying a project.","solutions":["Fix the JSON so it parses, e.g. `{ \"model\": \"openai/gpt-5.4-mini\" }` — validate with `cat .caveman/provider.json | python3 -m json.tool` or `jq .`.","Delete the file if you don't need a local pin (`rm .caveman/provider.json`) — its absence is valid and falls back to env credentials.","If it is a directory or has wrong permissions, remove/repair it so the path is a readable regular file.","Set `CAVE_MODEL` instead and remove the file to avoid the fragile local pin."],"exampleFix":"// before (.caveman/provider.json)\n{ \"model\": \"anthropic/claude-haiku-4-5\", }\n// after\n{ \"model\": \"anthropic/claude-haiku-4-5\" }","handlingStrategy":"validation","validationCode":"import { readFileSync } from \"node:fs\";\nfunction providerJsonIsValid(root: string): boolean {\n  try { JSON.parse(readFileSync(`${root}/.caveman/provider.json`, \"utf8\")); return true; }\n  catch (e) { return (e as NodeJS.ErrnoException).code === \"ENOENT\"; }\n}","typeGuard":"null","tryCatchPattern":"try {\n  await agent.run(task);\n} catch (e) {\n  if ((e as Error).message === \"caveman agent: invalid .caveman/provider.json\") {\n    console.error(\"Fix or delete .caveman/provider.json (must be valid JSON: {\\\"model\\\": \\\"provider/model\\\"})\");\n  } else throw e;\n}","preventionTips":["After hand-editing .caveman/provider.json, run it through a JSON parser (jq) before running the agent.","Prefer CAVE_MODEL over the local file pin; delete the file when unused.","Ensure .caveman/provider.json is a readable regular file, not a directory or truncated write."],"tags":["config","json","file"],"backgroundTag":"json-parse-error","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"}