JuliusBrussee/caveman · error · Error
cave_harness_model_identity_missing
cave_harness_model_identity_missing
Error message
cave_harness_model_identity_missing
What it means
After a harness call finishes, the response must report which model produced the output, and that reported model must be a non-empty string. `normalizedResponseModel` reads the model identity from the upstream response (optionally stripping a `provider/` prefix) so the adapter can verify the response model matches the plan; a missing or empty value means the evidence chain for model identity is incomplete, so the adapter fails closed. This is an upstream-response contract violation, not a caller configuration error.
Source
Thrown at packages/agent/src/adapters.ts:508
}
return {
provider: runtime.modelId.slice(0, separator),
model: runtime.modelId.slice(separator + 1),
upstreamVersion: runtime.eveVersion,
};
}
function expectedProviderModel(plan: CavePlan): { provider: string; model: string } {
const separator = plan.model.indexOf("/");
if (separator < 1 || separator === plan.model.length - 1) {
throw new Error("cave_harness_model_invalid");
}
return { provider: plan.model.slice(0, separator), model: plan.model.slice(separator + 1) };
}
function normalizedResponseModel(value: unknown, provider: string): string {
if (typeof value !== "string" || value.length === 0) {
throw new Error("cave_harness_model_identity_missing");
}
return value.startsWith(`${provider}/`) ? value.slice(provider.length + 1) : value;
}
function terminalFinishReason(value: unknown): boolean {
return typeof value === "string" && ["stop", "length", "content-filter", "other"].includes(value);
}
function record(value: unknown, error: string): Record<string, unknown> {
if (!isRecord(value)) throw new Error(error);
return value;
}
function strictInteger(value: unknown, error: string): number {
if (!Number.isSafeInteger(value) || Number(value) < 0) throw new Error(error);
return Number(value);
}
View on GitHub (pinned to 27d5a3981a)
Solutions
- If you stub or record harness responses, include a non-empty `model` string such as `"anthropic/claude-sonnet-4-5"`.
- Remove any middleware or proxy that strips fields from the upstream response body.
- If the error appears after upgrading the pinned harness package, reinstall the exact pinned version (e.g. Vercel AI SDK 7.0.43).
Example fix
// before (test stub)
const response = { text: "done", usage: { /* ... */ } };
// after (test stub)
const response = { model: "anthropic/claude-sonnet-4-5", text: "done", usage: { /* ... */ } }; Defensive patterns
Strategy: validation
Validate before calling
function hasResponseModel(response: unknown): boolean {
return typeof (response as Record<string, unknown> | null | undefined)?.model === "string" &&
((response as Record<string, unknown>).model as string).length > 0;
} Type guard
function hasModelField<T extends object>(v: T): v is T & { model: string } {
return typeof (v as Record<string, unknown>).model === "string" &&
((v as Record<string, unknown>).model as string).length > 0;
} Try / catch
try {
await adapter.run(request);
} catch (err) {
if (err instanceof Error && err.message === "cave_harness_model_identity_missing") {
// upstream response lacked model identity: fix the transport/stub, do not retry blindly
}
} Prevention
- Include the model field in every recorded/stubbed harness response.
- Keep the pinned harness SDK version so response shapes don't drift.
- Assert response contract fields in test fixtures once, in a shared helper.
When it happens
Trigger: The upstream harness (Vercel AI SDK / Eve / Mastra) returns a response object whose model field is `undefined`, `null`, `""`, or a non-string — e.g. a mock transport in tests, a response-shaping middleware that strips fields, or an upstream API change that renames the field.
Common situations: Unit tests stubbing harness responses with `{ text: "..." }` and forgetting `model`; an HTTP proxy or serializer dropping the model field; upgrading the pinned harness SDK after an API rename without regenerating the adapter evidence; using a custom fetch transport that fabricates responses.
Related errors
- cave_harness_model_invalid
- cave_harness_wire_contract_invalid
- cave_harness_signal_invalid
- caveman-code: model must use provider/model format
- option not found
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/d803ddd4e1d634a6.
Report an issue: GitHub.