{"record":{"id":"a278381f6855b044","repo":"Hmbown/CodeWhale","slug":"unsupported-engine-pet-event","errorCode":null,"errorMessage":"Unsupported Engine pet event.","messagePattern":"Unsupported Engine pet event\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/pet_watch/pet-native.js","lineNumber":1823,"sourceCode":"                    start(key, 'agent', 'agent', id('id'));\n                else\n                    this.pulse(key, at);\n                break;\n            }\n            case 'agent_complete':\n                finish(`agent:${id('id')}`);\n                break;\n            case 'approval_required':\n            case 'user_input_required':\n                this.waiting = this.add('human', 'human', at);\n                this.waiting.status = 'pending';\n                break;\n            case 'turn_complete':\n                this.active.clear();\n                this.waiting = undefined;\n                break;\n            case 'error': break;\n            default: throw new Error('Unsupported Engine pet event.');\n        }\n        // Receipt time is the error onset; never rewrite the operation's old start.\n        if (e.event === 'error' || e.failed === true)\n            this.add('error', 'error', at).status = 'error';\n    }\n    /** Waiting coverage comes from the existing typed shell's current request.\n     * It can extend a witnessed request, never invent one on a mid-turn attach. */\n    confirmWaiting(at, waiting) {\n        if (!waiting) {\n            this.waiting = undefined;\n            return;\n        }\n        if (this.waiting && at >= this.waiting.endTime)\n            this.waiting.endTime = at;\n    }\n    bucket(sequence) {\n        const end = (sequence + 1) * pet_telemetry_js_1.PET_BIN_MS;\n        const input = this.events.filter(e => e.startTime < end && e.endTime >= end - 12_400)","sourceCodeStart":1805,"sourceCodeEnd":1841,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tui/pet_watch/pet-native.js#L1805-L1841","documentation":"observe dispatches on e.event and only recognizes the Engine lifecycle events it models (turn_started, message_*/thinking_*/response_delta, tool_call_*, agent_*, approval_required, user_input_required, turn_complete, error). Any other event string reaches the default case and throws 'Unsupported Engine pet event.' The adapter is deliberately strict: unknown protocol events must fail loudly rather than be silently ignored, so the pet sim never misreads activity.","triggerScenarios":"Feeding raw EventMsg variants not in the adapter's switch (e.g. 'session_started', 'compaction_started', 'token_count', 'shutdown'); a new protocol event added upstream before the adapter learns it; typo'd event names like 'turn_start'; replaying a foreign telemetry tape with non-Engine event names.","commonSituations":"Protocol version drift: the Rust side added an event kind and the JS adapter is stale; a caller piping every session log event into observe instead of only lifecycle events; renaming an event in a refactor with one call site missed.","solutions":["Filter events to the supported set before calling observe, ignoring purely informational ones","Extend the switch with the new event case when the protocol legitimately added it (and bump the adapter with the protocol change)","Fix the event name spelling to match a supported variant","Pre-decode with a mapping table from raw EventMsg type to adapter event names"],"exampleFix":"// before\ntelemetry.observe({ event: msg.type, ... }, at); // msg.type may be 'compaction_started'\n// after\nconst SUPPORTED = new Set(['turn_started','message_started','thinking_started','response_delta','message_complete','thinking_complete','tool_call_started','tool_call_heartbeat','tool_call_complete','agent_spawned','agent_progress','agent_complete','approval_required','user_input_required','turn_complete','error']);\nif (SUPPORTED.has(msg.type)) telemetry.observe({ event: msg.type, ...meta }, at);","handlingStrategy":"validation","validationCode":"const SUPPORTED = new Set(['turn_started','message_started','thinking_started','response_delta','message_complete','thinking_complete','tool_call_started','tool_call_heartbeat','tool_call_complete','agent_spawned','agent_progress','agent_complete','approval_required','user_input_required','turn_complete','error']);\nif (SUPPORTED.has(msg.type)) telemetry.observe({ event: msg.type, ...project(meta) }, at);","typeGuard":"const isSupportedEngineEvent = (e) => typeof e?.event === 'string' && SUPPORTED.has(e.event);","tryCatchPattern":"try {\n  telemetry.observe(meta, at);\n} catch (err) {\n  if (err.message === 'Unsupported Engine pet event.') {\n    console.warn('ignoring unknown engine event', meta.event);\n    return;\n  }\n  throw err;\n}","preventionTips":["Filter the raw event stream to lifecycle events before observing","Map new protocol event kinds explicitly when the adapter is updated","Keep a single SUPPORTED set shared by producers and tests","Never forward raw log/event strings as e.event"],"tags":["telemetry","unsupported-event","protocol"],"backgroundTag":"invalid-enum-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}