Hmbown/CodeWhale · error · Error
Unknown category for
Error message
Unknown category for ${e.id}. What it means
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.
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.
Example fix
// before
{ id: 'a', category: 'llm_call', ... }
// after
{ id: 'a', category: 'inference', ... } // a value from CATEGORIES Defensive patterns
Strategy: validation
Validate before calling
import { CATEGORIES } from 'pet-native/model.js';
const unknown = events.filter(e => !CATEGORIES.includes(e.category));
if (unknown.length) console.warn('unknown categories:', [...new Set(unknown.map(e => e.category))]); Try / catch
try { buildPyramid(events) } catch (err) { const m = err.message.match(/Unknown category for (.+)\./); if (m) remapCategory(m[1]); throw err; } Prevention
- Source categories only from the exported CATEGORIES list
- Re-normalize old traces after library upgrades
- Reject ad-hoc category strings at event creation
When it happens
Trigger: 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.
Common situations: Schema drift after a library upgrade renamed/added categories, hand-written events with ad-hoc category labels, or events from another tool's taxonomy.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Unknown category for
- agent profile reasoning_effort must be one of: inherit…
- Choose approve or decline
- clipboard action must be "read" or "write
- computer action must be list, switch, register, spawn or…
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/08849340591131f9.
Report an issue: GitHub.
Appendix: source
Thrown at pet/ios/Resources/pet-native.js:1329
function buildPyramid(events, requestedDuration, maxBins = 16_384) {
if (!Number.isInteger(maxBins) || maxBins < 16 || maxBins > 1_048_576)
throw new Error('maxBins must be an integer in [16, 1048576].');
let duration = requestedDuration ?? 1;
for (const e of events)
duration = Math.max(duration, e.endTime, e.startTime, e.status === 'error' ? (0, model_js_1.errorOnsetOf)(e) : 0);
if (!Number.isFinite(duration) || duration < 0)
throw new Error('Signal duration must be finite and nonnegative.');
duration = Math.max(1, duration);
const binMs = 2 ** Math.ceil(Math.log2(Math.max(1, duration / (maxBins - 1))));
const length = Math.floor(duration / binMs) + 1, fine = emptyLevel(length, binMs);
const stride = length + 1;
const activeDiff = new Float64Array(model_js_1.CATEGORIES.length * stride), tokenDiff = new Float64Array(model_js_1.CATEGORIES.length * stride);
for (const e of events) {
if (!Number.isFinite(e.startTime) || !Number.isFinite(e.endTime) || e.startTime < 0 || e.endTime < e.startTime)
throw new Error(`Invalid interval for ${e.id}.`);
const channel = model_js_1.CATEGORIES.indexOf(e.category);
if (channel < 0)
throw new Error(`Unknown category for ${e.id}.`);
const a = Math.floor(e.startTime / binMs), b = Math.floor(e.endTime / binMs);
const at = channel * length, diff = channel * stride;
fine.onsets[at + a]++;
fine.cost[at + a] += e.cost ?? 0;
if (e.status === 'error')
fine.errors[at + Math.floor((0, model_js_1.errorOnsetOf)(e) / binMs)]++;
const d = e.endTime - e.startTime, tokens = e.outputTokens ?? 0;
if (d === 0) {
fine.outputTokens[at + a] += tokens;
continue;
}
if (a === b) {
fine.activeMs[at + a] += d;
fine.outputTokens[at + a] += tokens;
}
else {
const left = (a + 1) * binMs - e.startTime, right = e.endTime - b * binMs, tokenRate = tokens / d;
fine.activeMs[at + a] += left;View on GitHub (pinned to 433685b202)