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 runtime events are correlated through a request identity (approval_id/input_id, falling back to payload.id). If such an event lacks any of these identifiers, it cannot be paired with its required/decided/answered counterpart, so the import throws. Without the identity the request lifecycle cannot be reconstructed on the timeline.

Solutions

  1. Locate the offending record and add the correct approval_id/input_id (or id) to its payload.
  2. Re-export with a Codewhale version whose approval/user_input payloads include the request identity fields.
  3. Drop the unidentifiable record if its lifecycle counterpart is also absent.
  4. Validate payload ids for these event names before import.

Example fix

// before
{ "seq": 9, "event": "approval.required", "payload": { "tool": "bash" } }
// after
{ "seq": 9, "event": "approval.required", "payload": { "tool": "bash", "approval_id": "ap_123" } }
Defensive patterns

Strategy: validation

Validate before calling

const needsId = ['approval.required','approval.decided','approval.timeout','user_input.required','user_input.answered','user_input.canceled'];
const missing = records.filter(r => needsId.includes(r.event) && !(r.payload?.approval_id || r.payload?.input_id || r.payload?.id));
if (missing.length) throw new Error(`Records missing request identity: ${missing.map(r => r.seq).join(',')}`);

Type guard

const hasRequestId = (r) => Boolean(r?.payload?.approval_id || r?.payload?.input_id || r?.payload?.id);

Try / catch

try { importRuntime(records); } catch (e) { if (e.message.includes('missing its request identity')) dropOrFixRecordsWithoutId(records); else throw e; }

Prevention

When it happens

Trigger: Importing a runtime stream containing an approval.required/decided/timeout or user_input.required/answered/canceled record whose payload lacks approval_id (for approval.* events) or input_id (for user_input.* events) and has no id fallback.

Common situations: Exports from a Codewhale version that renamed or removed the id fields; hand-crafted or replayed test records omitting the id; partial payloads after a serialization bug or truncation.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/6c10c56c6a160ef0. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tui/pet_watch/pet-native.js:2382

                    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 = { ...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;
                }

View on GitHub (pinned to 73e0f67d83)