JuliusBrussee/caveman · error · Error
cave_${harness}_upstream_version_mismatch
cave_${harness}_upstream_version_mismatch
Error message
cave_${harness}_upstream_version_mismatch What it means
The installed harness version resolves and matches the adapter's pin, but the `upstreamVersion` the caller supplied in the harness identity does not equal the installed version. The pin chain requires lock, plan, installed package, and claimed identity to agree; a claim alone cannot authorize execution. This almost always means the identity object was built from a stale or hardcoded version string instead of the live runtime.
Source
Thrown at packages/agent/src/adapters.ts:592
function assertSupportedUpstream(
identity: HarnessAdapterIdentity,
expected: string,
harness: string,
pkg: string,
): void {
// The pin is enforced against the INSTALLED version, and the caller's claimed
// upstreamVersion must match what is actually installed — a claim alone can no
// longer authorize execution.
const installed = installedPackageVersion(pkg);
if (installed === undefined) {
throw new Error(`cave_${harness}_upstream_version_unresolvable`);
}
if (installed !== expected) {
throw new Error(`cave_${harness}_upstream_version_unsupported`);
}
if (identity.upstreamVersion !== installed) {
throw new Error(`cave_${harness}_upstream_version_mismatch`);
}
}
function canonicalRecord(value: Readonly<Record<string, unknown>>): Readonly<Record<string, unknown>> {
let encoded: string;
try {
encoded = stableStringify(value);
} catch {
throw new Error("cave_harness_wire_contract_invalid");
}
const decoded = JSON.parse(encoded) as unknown;
if (!isRecord(decoded)) throw new Error("cave_harness_wire_contract_invalid");
return decoded;
}
function deepFreeze<T>(value: T): T {
if (value !== null && typeof value === "object") {
Object.freeze(value);View on GitHub (pinned to 27d5a3981a)
Solutions
- Update the `upstreamVersion` in the identity you pass to match the installed version reported in the error.
- Better: derive the identity's `upstreamVersion` at runtime from the installed package (or obtain the identity from the framework) instead of hardcoding it.
- After any dependency change, regenerate lock/plan artifacts that embed the upstream version.
Example fix
// before
const identity = { upstreamVersion: "7.0.40", /* ... */ }; // installed is 7.0.43
// after
const identity = { upstreamVersion: "7.0.43", /* ... */ }; Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from "node:fs";
function installedVersion(pkg: string): string {
return JSON.parse(
readFileSync(fileURLToPath(import.meta.resolve(`${pkg}/package.json`)), "utf8"),
).version as string;
}
// derive, never hardcode:
const identity = { upstreamVersion: installedVersion("ai"), /* ... */ }; Try / catch
try {
await adapter.run(request);
} catch (err) {
if (err instanceof Error && err.message.endsWith("_upstream_version_mismatch")) {
// rebuild identity from the installed version and retry once
}
} Prevention
- Never hardcode upstreamVersion; resolve it from the installed package at runtime.
- Regenerate lock/plan artifacts after any dependency change.
- Treat serialized identities as stale after reinstalling dependencies.
When it happens
Trigger: Passing a `HarnessAdapterIdentity` with `upstreamVersion: "7.0.40"` while 7.0.43 is installed; caching an identity across an `npm install` that bumped the pinned-but-then-reinstalled package; building identity from a constant instead of reading the installed package version.
Common situations: Hardcoding the upstream version in app code and forgetting to update it after a reinstall; reusing a serialized identity from a previous session/lock file; CI image rebuilt with a patched harness version while the app config still names the old one.
Related errors
- cave_${harness}_upstream_version_unresolvable
- cave_${harness}_upstream_version_unsupported
- cave_harness_model_invalid
- cave_harness_model_identity_missing
- cave_harness_wire_contract_invalid
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/8d361ec6b7ae39e8.
Report an issue: GitHub.