{"record":{"id":"9c762ae78faf5d91","repo":"Hmbown/CodeWhale","slug":"runtime-eventname-is-missing-its-request-identity-pet-native","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":"pet/ios/Resources/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/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/pet/ios/Resources/pet-native.js#L2364-L2400","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst events = runtime.import(file, threadId); // throws on id-less approval event\n// after\nfor (const r of records) {\n  if (r.event?.startsWith('approval.') && !r.payload?.approval_id && !r.payload?.id)\n    throw new Error(`seq ${r.seq}: approval event missing approval_id`);\n}\nconst events = runtime.import(file, threadId);","handlingStrategy":"validation","validationCode":"const idLess = records.filter(r =>\n  /^(approval|user_input)\\./.test(r.event ?? '') &&\n  !(r.payload?.approval_id ?? r.payload?.input_id ?? r.payload?.id));\nif (idLess.length) throw new Error(`${idLess.length} approval/user_input records lack a request id (e.g. seq ${idLess[0].seq})`);","typeGuard":"function hasRequestIdentity(rec) {\n  const p = rec?.payload;\n  const kind = rec?.event?.startsWith('approval.') ? 'approval' : 'user_input';\n  return Boolean(p && (p[kind === 'approval' ? 'approval_id' : 'input_id'] ?? p.id));\n}","tryCatchPattern":"try {\n  runtime.import(file, threadId);\n} catch (e) {\n  if (String(e.message).includes('missing its request identity')) {\n    console.error('An approval/user_input record lost its id; re-export or repair the payload.');\n  } else throw e;\n}","preventionTips":["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."],"tags":["import","approval","missing-field"],"backgroundTag":"missing-required-argument","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}