{"record":{"id":"6c10c56c6a160ef0","repo":"Hmbown/CodeWhale","slug":"runtime-eventname-is-missing-its-request-identity","errorCode":null,"errorMessage":"Runtime ${eventName} is missing its request identity.","messagePattern":"Runtime (.+?) is missing its request identity\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/pet_watch/pet-native.js","lineNumber":2382,"sourceCode":"                    attributes: { 'codewhale.seq': rec.seq, 'codewhale.turn_id': turnId, 'whalesong.container': true,\n                        ...(statusOf(turn.status ?? payload.status) === 'error' ? { 'whalesong.error_onset_ms': relative } : {}) },\n                    payload: { input_summary: clip(turn.input_summary) }, raw: rec,\n                };\n                if (existing >= 0) {\n                    const prior = events[existing];\n                    this.measure(prior, { ...next, startTime: prior.startTime });\n                }\n                else\n                    this.push(next);\n                continue;\n            }\n            if (eventName === 'turn.lifecycle')\n                continue;\n            if (['approval.required', 'approval.decided', 'approval.timeout', 'user_input.required', 'user_input.answered', 'user_input.canceled'].includes(eventName)) {\n                const kind = eventName.startsWith('approval.') ? 'approval' : 'user_input';\n                const requestId = str(payload[kind === 'approval' ? 'approval_id' : 'input_id']) ?? str(payload.id);\n                if (!requestId)\n                    throw new Error(`Runtime ${eventName} is missing its request identity.`);\n                const key = JSON.stringify([turnId ?? '', kind, requestId]);\n                const prior = requests.get(key), required = eventName.endsWith('.required');\n                if (required && prior)\n                    continue;\n                if (!required && prior) {\n                    const next = { ...prior, attributes: { ...prior.attributes },\n                        endTime: Math.max(prior.startTime, relative), openEnded: false,\n                        status: eventName === 'approval.decided' || eventName === 'user_input.answered' ? 'success' : 'unknown' };\n                    if (payload.auto === true) {\n                        // Automatic consent has a receipt, but never asked the human to wait.\n                        next.category = 'orchestration';\n                        delete next.attributes['whalesong.waiting'];\n                        next.attributes['whalesong.container'] = true;\n                    }\n                    this.measure(prior, next);\n                    requests.delete(key);\n                    continue;\n                }","sourceCodeStart":2364,"sourceCodeEnd":2400,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tui/pet_watch/pet-native.js#L2364-L2400","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Locate the offending record and add the correct approval_id/input_id (or id) to its payload.","Re-export with a Codewhale version whose approval/user_input payloads include the request identity fields.","Drop the unidentifiable record if its lifecycle counterpart is also absent.","Validate payload ids for these event names before import."],"exampleFix":"// before\n{ \"seq\": 9, \"event\": \"approval.required\", \"payload\": { \"tool\": \"bash\" } }\n// after\n{ \"seq\": 9, \"event\": \"approval.required\", \"payload\": { \"tool\": \"bash\", \"approval_id\": \"ap_123\" } }","handlingStrategy":"validation","validationCode":"const needsId = ['approval.required','approval.decided','approval.timeout','user_input.required','user_input.answered','user_input.canceled'];\nconst missing = records.filter(r => needsId.includes(r.event) && !(r.payload?.approval_id || r.payload?.input_id || r.payload?.id));\nif (missing.length) throw new Error(`Records missing request identity: ${missing.map(r => r.seq).join(',')}`);","typeGuard":"const hasRequestId = (r) => Boolean(r?.payload?.approval_id || r?.payload?.input_id || r?.payload?.id);","tryCatchPattern":"try { importRuntime(records); } catch (e) { if (e.message.includes('missing its request identity')) dropOrFixRecordsWithoutId(records); else throw e; }","preventionTips":["Ensure approval/user_input payloads always carry approval_id/input_id.","Validate these event kinds' payload ids before import.","Re-export after version upgrades if id fields were renamed.","Don't craft test records without request ids."],"tags":["runtime","approval","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T21:17:16.096Z"}