Hmbown/CodeWhale · error · Error

Runtime is missing its request identity.

Error message

Runtime ${eventName} is missing its request identity.

What it means

Thrown when an approval or user_input lifecycle event lacks any request identifier: neither the kind-specific field (approval_id / input_id) nor a generic id is present on its payload. The importer keys pending requests by [turnId, kind, requestId] to pair .required with its terminal event, so a record without an identity cannot be tracked and aborts the import. The event name is included in the message.

Solutions

  1. Locate the offending record for the named event and restore its approval_id/input_id or id payload field.
  2. Re-export the thread to get complete records.
  3. If a schema rename is the cause, align importer and exporter versions or map the new field name onto the expected one.
  4. Pre-validate that all approval/user_input records carry an id before importing.

Example fix

// before
const events = runtime.import(file, threadId); // throws on id-less approval event
// after
for (const r of records) {
  if (r.event?.startsWith('approval.') && !r.payload?.approval_id && !r.payload?.id)
    throw new Error(`seq ${r.seq}: approval event missing approval_id`);
}
const events = runtime.import(file, threadId);
Defensive patterns

Strategy: validation

Validate before calling

const idLess = records.filter(r =>
  /^(approval|user_input)\./.test(r.event ?? '') &&
  !(r.payload?.approval_id ?? r.payload?.input_id ?? r.payload?.id));
if (idLess.length) throw new Error(`${idLess.length} approval/user_input records lack a request id (e.g. seq ${idLess[0].seq})`);

Type guard

function hasRequestIdentity(rec) {
  const p = rec?.payload;
  const kind = rec?.event?.startsWith('approval.') ? 'approval' : 'user_input';
  return Boolean(p && (p[kind === 'approval' ? 'approval_id' : 'input_id'] ?? p.id));
}

Try / catch

try {
  runtime.import(file, threadId);
} catch (e) {
  if (String(e.message).includes('missing its request identity')) {
    console.error('An approval/user_input record lost its id; re-export or repair the payload.');
  } else throw e;
}

Prevention

When it happens

Trigger: Importing a runtime file containing an approval.required/.decided/.timeout or user_input.required/.answered/.canceled record whose payload has no approval_id (or input_id) and no id field, detected at pet/ios/Resources/pet-native.js:2382.

Common situations: A truncated or hand-edited export that dropped payload fields; a schema change in a newer/older Codewhale version renaming the id field; exporter bugs that emitted control events without their identity; manually synthesized records in tests.

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@433685b202 (2026-09-15). Data as JSON: /api/errors/9c762ae78faf5d91. Report an issue: GitHub.

Appendix: source

Thrown at pet/ios/Resources/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 433685b202)