Hmbown/CodeWhale · error · Error

Runtime is missing its request identity.

Error message

Runtime ${eventName} is missing its request identity.

What it means

Approval and user-input lifecycle events in a Codewhale runtime stream must carry a request identifier (approval_id/input_id, or a generic id). Without it the journal cannot correlate the request with its later decision/answer/timeout, so the library rejects the event instead of building an unmatchable entry.

Solutions

  1. Inspect the failing event's payload and ensure it includes approval_id (for approval.*) or input_id (for user_input.*) — payload.id is accepted as a fallback.
  2. Re-export the runtime file from a runtime version that emits request identities (runtime-events/v2).
  3. If events were post-processed, restore the id field instead of stripping it.
  4. Check the runtime source that emits these events and add the identifier there if it is genuinely missing.

Example fix

// before
{ "event": "approval.decided", "payload": { "turn_id": "t1", "decision": "allow" } }
// after
{ "event": "approval.decided", "payload": { "turn_id": "t1", "approval_id": "apr_42", "decision": "allow" } }
Defensive patterns

Strategy: validation

Validate before calling

function hasRequestId(rec) {
  const ev = rec?.event ?? '';
  if (!/^(approval|user_input)\./.test(ev)) return true;
  const kind = ev.startsWith('approval.') ? 'approval' : 'user_input';
  const p = rec.payload ?? {};
  return typeof (p[kind === 'approval' ? 'approval_id' : 'input_id'] ?? p.id) === 'string';
}

Type guard

const hasRequestIdentity = (p) => typeof (p?.approval_id ?? p?.input_id ?? p?.id) === 'string' && (p?.approval_id ?? p?.input_id ?? p?.id).length > 0;

Try / catch

try {
  const trace = fromCodewhaleRuntime(records);
} catch (e) {
  if (e.message.includes('missing its request identity')) {
    console.error('approval/user_input event without id; re-export from a v2 runtime');
  } else throw e;
}

Prevention

When it happens

Trigger: Importing a runtime events file where an approval.required / approval.decided / approval.timeout / user_input.required / user_input.answered / user_input.canceled record's payload lacks both the kind-specific id field and a fallback payload.id.

Common situations: A runtime version or exporter that renamed or dropped the id field; hand-edited or redacted event payloads; a custom event emitter emitting approval/user_input events without the identifier; older event format (not runtime-events/v2) fed to this importer.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/22b22802c5db2eda. Report an issue: GitHub.

Appendix: source

Thrown at pet/src/core/codewhale.ts:450

          startTime: start, endTime: Math.max(start, end), openEnded: eventName !== 'turn.completed',
          agentId, name: 'turn', category: 'orchestration', model,
          inputTokens: num(usage.input_tokens), outputTokens: num(usage.output_tokens),
          status: statusOf(turn.status ?? payload.status), latency: num(turn.duration_ms),
          attributes: { 'codewhale.seq': rec.seq, 'codewhale.turn_id': turnId, 'whalesong.container': true,
            ...(statusOf(turn.status ?? payload.status) === 'error' ? { 'whalesong.error_onset_ms': relative } : {}) },
          payload: { input_summary: clip(turn.input_summary) }, raw: rec,
        };
        if (existing >= 0) {
          const prior = events[existing]!; this.measure(prior, { ...next, startTime: prior.startTime });
        }
        else this.push(next);
        continue;
      }
      if (eventName === 'turn.lifecycle') continue;
      if (['approval.required', 'approval.decided', 'approval.timeout', 'user_input.required', 'user_input.answered', 'user_input.canceled'].includes(eventName)) {
        const kind = eventName.startsWith('approval.') ? 'approval' : 'user_input';
        const requestId = str(payload[kind === 'approval' ? 'approval_id' : 'input_id']) ?? str(payload.id);
        if (!requestId) throw new Error(`Runtime ${eventName} is missing its request identity.`);
        const key = JSON.stringify([turnId ?? '', kind, requestId]);
        const prior = requests.get(key), required = eventName.endsWith('.required');
        if (required && prior) continue;
        if (!required && prior) {
          const next: WhaleEvent = { ...prior, attributes: { ...prior.attributes },
            endTime: Math.max(prior.startTime, relative), openEnded: false,
            status: eventName === 'approval.decided' || eventName === 'user_input.answered' ? 'success' : 'unknown' };
          if (payload.auto === true) {
            // Automatic consent has a receipt, but never asked the human to wait.
            next.category = 'orchestration'; delete next.attributes['whalesong.waiting'];
            next.attributes['whalesong.container'] = true;
          }
          this.measure(prior, next); requests.delete(key); continue;
        }
        const automatic = payload.auto === true;
        const event: WhaleEvent = {
          schemaVersion: 1, id: `request:${key}:${rec.seq}`, traceId: threadId,
          parentId: turnId ? `turn:${turnId}` : undefined, startTime: relative, endTime: relative,

View on GitHub (pinned to 433685b202)