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
- Locate the offending record for the named event and restore its approval_id/input_id or id payload field.
- Re-export the thread to get complete records.
- If a schema rename is the cause, align importer and exporter versions or map the new field name onto the expected one.
- 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
- Check approval/user_input payloads for their id fields before import.
- Keep exporter/importer versions aligned on payload field names.
- Avoid hand-editing exports; regenerate instead.
- Cover exports with a schema check that all lifecycle events carry ids.
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
- A managed, project or plugin connector already uses this…
- agent profile may not disable approval_required
- Antigravity import requires an agy_cli grant, not
- bundle carries [global] entries; importing them into a…
- bundle carries [project] entries; import it with --project…
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)