{"record":{"id":"514de8bb26fa60c0","repo":"JuliusBrussee/caveman","slug":"cave-harness-model-invalid","errorCode":"cave_harness_model_invalid","errorMessage":"cave_harness_model_invalid","messagePattern":"cave_harness_model_invalid","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/agent/src/adapters.ts","lineNumber":501,"sourceCode":"      runtime.modelId.startsWith(\"dynamic:\")) {\n    throw new Error(\"cave_eve_runtime_identity_missing\");\n  }\n  const separator = runtime.modelId.indexOf(\"/\");\n  if (separator < 1 || separator === runtime.modelId.length - 1 ||\n      typeof runtime.eveVersion !== \"string\" || runtime.eveVersion.length === 0) {\n    throw new Error(\"cave_eve_runtime_identity_missing\");\n  }\n  return {\n    provider: runtime.modelId.slice(0, separator),\n    model: runtime.modelId.slice(separator + 1),\n    upstreamVersion: runtime.eveVersion,\n  };\n}\n\nfunction expectedProviderModel(plan: CavePlan): { provider: string; model: string } {\n  const separator = plan.model.indexOf(\"/\");\n  if (separator < 1 || separator === plan.model.length - 1) {\n    throw new Error(\"cave_harness_model_invalid\");\n  }\n  return { provider: plan.model.slice(0, separator), model: plan.model.slice(separator + 1) };\n}\n\nfunction normalizedResponseModel(value: unknown, provider: string): string {\n  if (typeof value !== \"string\" || value.length === 0) {\n    throw new Error(\"cave_harness_model_identity_missing\");\n  }\n  return value.startsWith(`${provider}/`) ? value.slice(provider.length + 1) : value;\n}\n\nfunction terminalFinishReason(value: unknown): boolean {\n  return typeof value === \"string\" && [\"stop\", \"length\", \"content-filter\", \"other\"].includes(value);\n}\n\nfunction record(value: unknown, error: string): Record<string, unknown> {\n  if (!isRecord(value)) throw new Error(error);\n  return value;","sourceCodeStart":483,"sourceCodeEnd":519,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/766dce6b1394ebb56a3090748d5a0240a5aefb36/packages/agent/src/adapters.ts#L483-L519","documentation":"expectedProviderModel requires plan.model to be a 'provider/model' string with a non-empty provider before the first '/' and a non-empty model after it. It throws when the '/' separator is missing, at index 0, or the last character, because the adapter can never split plan.model into the provider/model pair that harness execution and response identity are matched against.","triggerScenarios":"Calling createVercelAISDKAdapter or createMastraAdapter (or any createHarnessAdapter run reaching harnessExecution) with a CavePlan whose model is \"claude-sonnet-4-5\" (no slash), \"/claude-sonnet-4-5\" (empty provider), or \"anthropic/\" (empty model).","commonSituations":"Hand-assembling a CavePlan instead of taking it from the compile/build pipeline; a config layer storing just the model name without the provider prefix; plan serialization code that trims or rewrites the '/'-joined identifier.","solutions":["Use a plan produced by the framework's compile pipeline, which guarantees the provider/model shape","If building the plan yourself, set plan.model to 'provider/model', e.g. \"anthropic/claude-sonnet-4-5\"","Add a guard on plan.model before creating/running the adapter (see type guard below)"],"exampleFix":"// before\nconst plan = { model: \"claude-sonnet-4-5\", /* ... */ };\nawait adapter.run({ plan, /* ... */ }); // throws cave_harness_model_invalid\n\n// after\nconst plan = { model: \"anthropic/claude-sonnet-4-5\", /* ... */ };\nawait adapter.run({ plan, /* ... */ });","handlingStrategy":"type-guard","validationCode":"const separator = plan.model.indexOf(\"/\");\nif (separator < 1 || separator === plan.model.length - 1) {\n  throw new Error(`plan.model must be 'provider/model', got: ${plan.model}`);\n}","typeGuard":"function isProviderModelString(value: string): value is `${string}/${string}` {\n  const separator = value.indexOf(\"/\");\n  return separator > 0 && separator < value.length - 1;\n}","tryCatchPattern":"try {\n  await adapter.run(request);\n} catch (error) {\n  if (error instanceof Error && error.message === \"cave_harness_model_invalid\") {\n    // plan.model lacks the required provider/model shape — rebuild the plan\n    // through the compile pipeline or fix the model identifier.\n  }\n  throw error;\n}","preventionTips":["Take plans from the framework compile pipeline rather than hand-building them","Store model identifiers everywhere as 'provider/model', never bare model names","Assert isProviderModelString(plan.model) at the boundary where plans enter your code"],"tags":["plan","model-id","adapter","validation"],"backgroundTag":"invalid-model-id-format","analyzedSha":"766dce6b1394ebb56a3090748d5a0240a5aefb36","analyzedAt":"2026-08-18T03:14:35.516Z","contentChangedAt":"2026-08-18T03:14:35.516Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}