{"record":{"id":"08849340591131f9","repo":"Hmbown/CodeWhale","slug":"unknown-category-for-e-id-pet-native","errorCode":null,"errorMessage":"Unknown category for ${e.id}.","messagePattern":"Unknown category for (.+?)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"pet/ios/Resources/pet-native.js","lineNumber":1329,"sourceCode":"function buildPyramid(events, requestedDuration, maxBins = 16_384) {\n    if (!Number.isInteger(maxBins) || maxBins < 16 || maxBins > 1_048_576)\n        throw new Error('maxBins must be an integer in [16, 1048576].');\n    let duration = requestedDuration ?? 1;\n    for (const e of events)\n        duration = Math.max(duration, e.endTime, e.startTime, e.status === 'error' ? (0, model_js_1.errorOnsetOf)(e) : 0);\n    if (!Number.isFinite(duration) || duration < 0)\n        throw new Error('Signal duration must be finite and nonnegative.');\n    duration = Math.max(1, duration);\n    const binMs = 2 ** Math.ceil(Math.log2(Math.max(1, duration / (maxBins - 1))));\n    const length = Math.floor(duration / binMs) + 1, fine = emptyLevel(length, binMs);\n    const stride = length + 1;\n    const activeDiff = new Float64Array(model_js_1.CATEGORIES.length * stride), tokenDiff = new Float64Array(model_js_1.CATEGORIES.length * stride);\n    for (const e of events) {\n        if (!Number.isFinite(e.startTime) || !Number.isFinite(e.endTime) || e.startTime < 0 || e.endTime < e.startTime)\n            throw new Error(`Invalid interval for ${e.id}.`);\n        const channel = model_js_1.CATEGORIES.indexOf(e.category);\n        if (channel < 0)\n            throw new Error(`Unknown category for ${e.id}.`);\n        const a = Math.floor(e.startTime / binMs), b = Math.floor(e.endTime / binMs);\n        const at = channel * length, diff = channel * stride;\n        fine.onsets[at + a]++;\n        fine.cost[at + a] += e.cost ?? 0;\n        if (e.status === 'error')\n            fine.errors[at + Math.floor((0, model_js_1.errorOnsetOf)(e) / binMs)]++;\n        const d = e.endTime - e.startTime, tokens = e.outputTokens ?? 0;\n        if (d === 0) {\n            fine.outputTokens[at + a] += tokens;\n            continue;\n        }\n        if (a === b) {\n            fine.activeMs[at + a] += d;\n            fine.outputTokens[at + a] += tokens;\n        }\n        else {\n            const left = (a + 1) * binMs - e.startTime, right = e.endTime - b * binMs, tokenRate = tokens / d;\n            fine.activeMs[at + a] += left;","sourceCodeStart":1311,"sourceCodeEnd":1347,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/pet/ios/Resources/pet-native.js#L1311-L1347","documentation":"buildPyramid maps each event onto a channel via CATEGORIES.indexOf(e.category); an unknown category yields -1 and triggers this error, naming the event id. Categories must come from the library's fixed CATEGORIES list so channel arrays can be preallocated.","triggerScenarios":"Passing events whose category is missing, renamed, or outside the current CATEGORIES enum — e.g. events from an older schema version or a custom category string.","commonSituations":"Schema drift after a library upgrade renamed/added categories, hand-written events with ad-hoc category labels, or events from another tool's taxonomy.","solutions":["Set each event's category to one of the values in the exported CATEGORIES array.","Check offline first: events.filter(e => !CATEGORIES.includes(e.category)) and fix those ids.","Re-import the trace through importTrace so categories are normalized to the current schema."],"exampleFix":"// before\n{ id: 'a', category: 'llm_call', ... }\n// after\n{ id: 'a', category: 'inference', ... } // a value from CATEGORIES","handlingStrategy":"validation","validationCode":"import { CATEGORIES } from 'pet-native/model.js';\nconst unknown = events.filter(e => !CATEGORIES.includes(e.category));\nif (unknown.length) console.warn('unknown categories:', [...new Set(unknown.map(e => e.category))]);","typeGuard":null,"tryCatchPattern":"try { buildPyramid(events) } catch (err) { const m = err.message.match(/Unknown category for (.+)\\./); if (m) remapCategory(m[1]); throw err; }","preventionTips":["Source categories only from the exported CATEGORIES list","Re-normalize old traces after library upgrades","Reject ad-hoc category strings at event creation"],"tags":["enum","validation","events"],"backgroundTag":"invalid-enum-value","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"}