{"record":{"id":"22af6b27a1e24b78","repo":"Hmbown/CodeWhale","slug":"select-one-trace-for-the-pet-telemetry","errorCode":null,"errorMessage":"Select one trace for the pet.","messagePattern":"Select one trace for the pet\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"pet/src/core/pet-telemetry.ts","lineNumber":85,"sourceCode":"/** Compile a single trace. Unknown-duration spans provide onsets, not occupancy.\n * Updates of the same trace/id replace earlier snapshots rather than double count.\n * An endpoint onset gets its own bucket; intervals use [start, end). */\nexport function compilePetTelemetry(input: readonly WhaleEvent[], durationMs = 0, firstSequence = 0, originMs = 0): PetBucket[] {\n  if (input.length > 250_000) throw new Error('Pet input exceeds 250000 events.');\n  if (!Number.isFinite(durationMs) || durationMs < 0) throw new Error('Invalid pet duration.');\n  if (!Number.isSafeInteger(firstSequence) || firstSequence < 0) throw new Error('Invalid first pet bucket.');\n  if (!Number.isFinite(originMs)) throw new Error('Invalid pet clock origin.');\n  durationMs = Math.max(0, durationMs - originMs);\n  const unique = new Map<string, WhaleEvent>();\n  const traces = new Set<string>();\n  for (const e of input) {\n    if (e.schemaVersion !== 1 || !e.id || !e.traceId || !CATEGORIES.includes(e.category)\n      || !Number.isFinite(e.startTime) || !Number.isFinite(e.endTime)\n      || e.startTime < 0 || e.endTime < e.startTime || !e.attributes)\n      throw new Error('Invalid event-v1 pet input. Import through importTrace first.');\n    traces.add(e.traceId); unique.set(keyOf(e), e);\n  }\n  if (traces.size > 1) throw new Error('Select one trace for the pet.');\n  const parents = new Set([...unique.values()].filter(e => e.parentId).map(e => e.parentId!));\n  const events = [...unique.values()].filter(e => !isContainer(e)\n    && !(e.category === 'orchestration' && parents.has(e.id)))\n    .map(e => ({ ...e, startTime: e.startTime - originMs, endTime: (e.openEnded ? e.startTime : e.endTime) - originMs,\n      attributes: e.attributes['whalesong.error_onset_ms'] === undefined ? e.attributes\n        : { ...e.attributes, 'whalesong.error_onset_ms': errorOnsetOf(e) - originMs } }))\n    .sort((a, b) => a.startTime - b.startTime || order(a.id, b.id));\n  let lastOnset = 0;\n  for (const e of events) { durationMs = Math.max(durationMs, e.endTime); lastOnset = Math.max(lastOnset, e.startTime); }\n  const failures = events.filter(e => e.category === 'error' || e.status === 'error').map(errorOnsetOf).sort((a, b) => a - b);\n  if (failures.length) lastOnset = Math.max(lastOnset, failures[failures.length - 1]);\n  const count = Math.max(1, Math.ceil(durationMs / PET_BIN_MS), Math.floor(lastOnset / PET_BIN_MS) + 1);\n  if (count - firstSequence > 216_000 || count > PET_MAX_SECONDS * 2.5) throw new Error('Pet replay exceeds 24 hours; select a shorter trace.');\n  const index = new IntervalIndex(events), result: PetBucket[] = [];\n  const recent: WhaleEvent[] = [], names = new Map<string, number>();\n  let next = 0, expired = 0, nextFailure = 0;\n  for (let sequence = firstSequence; sequence < count; sequence++) {\n    const start = sequence * PET_BIN_MS, end = start + PET_BIN_MS;","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/433685b2024e7bc4c99e1e2e326bcad39b4d9d65/pet/src/core/pet-telemetry.ts#L67-L103","documentation":"Generic guard error meaning the pet view was asked to render without a single trace being selected. The pet visualization requires exactly one trace as its subject; this fires when zero (or ambiguous multiple) traces are available/selected, telling the caller to narrow the selection first.","triggerScenarios":"Calling compilePetTelemetry with events from two or more different traceId values, even after dedup by keyOf.","commonSituations":"Concatenating traces from a batch export; a filter accidentally keeping events from sibling traces; importing a whole session instead of one selected trace.","solutions":["Filter input to a single traceId before calling compilePetTelemetry.","If the input came from a UI export, select only one trace.","Group events by traceId and compile each group separately."],"exampleFix":"// before\ncompilePetTelemetry(allEvents);\n// after\nconst traceId = allEvents[0].traceId;\ncompilePetTelemetry(allEvents.filter(e => e.traceId === traceId));","handlingStrategy":"validation","validationCode":"const ids = new Set(events.map(e => e.traceId));\nif (ids.size > 1) throw new Error('Multiple traces: ' + [...ids].join(','));","typeGuard":null,"tryCatchPattern":"try { compilePetTelemetry(events); } catch (e) { if (e.message === 'Select one trace for the pet.') promptUserToSelectTrace(events); }","preventionTips":["Filter by traceId as the first ingestion step.","Never concatenate raw trace exports."],"tags":["validation","input"],"backgroundTag":"invalid-argument-value","analyzedSha":"433685b2024e7bc4c99e1e2e326bcad39b4d9d65","analyzedAt":"2026-09-15T12:24:24.634Z","contentChangedAt":"2026-09-15T12:24:24.634Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}