JuliusBrussee/caveman · error · Error

cave_eve_runtime_identity_missing

cave_eve_runtime_identity_missing

Error message

cave_eve_runtime_identity_missing

What it means

`eveRuntimeIdentity` scans the session's events for `session.started` events that carry a `data.runtime` record and requires exactly one. Zero matches (no `session.started`, or one without a `runtime` object) or more than one (concatenated or replayed logs, merged sessions) throws `cave_eve_runtime_identity_missing` at line 480. That single event is what makes provider/model/upstreamVersion identity provable, so ambiguity or absence is fatal to the evidence chain.

Solutions

  1. Inspect `result.events` and assert exactly one `{ type: 'session.started', data: { runtime: { … } } }` exists
  2. Remove any dedup/merge logic that duplicates or drops `session.started`
  3. Confirm the runtime populates `data.runtime` on session start for the pinned Eve version (0.29.2)
Defensive patterns

Strategy: validation

Validate before calling

// probe: the session must yield exactly one session.started with a runtime
const events = (await (await session.send({ message: 'ping' })).result()).events;
const starts = events.filter((ev) =>
  ev?.type === 'session.started' && ev?.data?.runtime && typeof ev.data.runtime === 'object');
if (starts.length !== 1) {
  throw new Error(`expected 1 session.started with runtime, got ${starts.length}`);
}

Type guard

function hasSingleSessionStart(events: unknown[]): boolean {
  return events.filter((ev) => {
    const e = ev as { type?: string; data?: { runtime?: unknown } };
    return e?.type === 'session.started' &&
      typeof e.data?.runtime === 'object' && e.data.runtime !== null;
  }).length === 1;
}

Prevention

When it happens

Trigger: An event log filtered so `session.started` is dropped; replaying or concatenating two sessions' event arrays into one; middleware merging duplicate start events; a runtime record renamed by an Eve version change.

Common situations: Event-logging pipelines with allowlists that miss `session.started`; tests replaying recorded event fixtures with duplicates; aggregators appending events from multiple sessions.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@766dce6b13 (2026-08-18). Data as JSON: /api/errors/05c95d0efdb95bf8. Report an issue: GitHub.

Appendix: source

Thrown at packages/agent/src/adapters.ts:480

    totalTokens: strictInteger(value.totalTokens, error),
  };
  if (usage.totalTokens !== usage.inputTokens + usage.outputTokens +
      usage.cacheReadTokens + usage.cacheWriteTokens ||
      usage.reasoningTokens > usage.outputTokens) {
    throw new Error(error);
  }
  return usage;
}

function eveRuntimeIdentity(events: unknown[]): {
  provider: string;
  model: string;
  upstreamVersion: string;
} {
  const starts = events.filter((event) =>
    isRecord(event) && event.type === "session.started" && isRecord(event.data) &&
    isRecord(event.data.runtime));
  if (starts.length !== 1) throw new Error("cave_eve_runtime_identity_missing");
  const runtime = (starts[0] as { data: { runtime: Record<string, unknown> } }).data.runtime;
  if (typeof runtime.modelId !== "string" || runtime.modelId.length === 0 ||
      runtime.modelId.startsWith("dynamic:")) {
    throw new Error("cave_eve_runtime_identity_missing");
  }
  const separator = runtime.modelId.indexOf("/");
  if (separator < 1 || separator === runtime.modelId.length - 1 ||
      typeof runtime.eveVersion !== "string" || runtime.eveVersion.length === 0) {
    throw new Error("cave_eve_runtime_identity_missing");
  }
  return {
    provider: runtime.modelId.slice(0, separator),
    model: runtime.modelId.slice(separator + 1),
    upstreamVersion: runtime.eveVersion,
  };
}

function expectedProviderModel(plan: CavePlan): { provider: string; model: string } {

View on GitHub (pinned to 766dce6b13)