{"record":{"id":"e6852eea8f21fe66","repo":"Hmbown/CodeWhale","slug":"codewhale-runtime-file-contained-only-stream-deltas-or","errorCode":null,"errorMessage":"Codewhale runtime file contained only stream deltas or unreadable records.","messagePattern":"Codewhale runtime file contained only stream deltas or unreadable records\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/pet_watch/pet-native.js","lineNumber":2482,"sourceCode":"            });\n        }\n        this.origin = origin;\n        this.model = model;\n        this.threadName = threadName;\n        this.skippedDeltas = skippedDeltas;\n    }\n    snapshot() {\n        const { events, open, requests, origin, model, skippedDeltas, filename } = this;\n        const threadId = this.threadId ?? filename, threadName = this.threadName ?? threadId;\n        const warnings = [];\n        if (skippedDeltas)\n            warnings.push(`Dropped ${skippedDeltas.toLocaleString()} item.delta records; they are token stream fragments, not spans. Item start/end remain the source of duration.`);\n        for (const [id] of open)\n            warnings.push(`Item ${id} started and never completed in this file; duration remains unknown.`);\n        for (const request of requests.values())\n            warnings.push(`Request ${request.id} has no terminal receipt; its duration remains unknown in this file.`);\n        if (!events.length)\n            throw new Error('Codewhale runtime file contained only stream deltas or unreadable records.');\n        const base = events.reduce((m, e) => Math.min(m, e.startTime), events[0].startTime);\n        const normalized = events.map(event => ({ ...event, startTime: event.startTime - base, endTime: event.endTime - base,\n            attributes: { ...event.attributes, ...(event.attributes['whalesong.error_onset_ms'] !== undefined\n                    ? { 'whalesong.error_onset_ms': (0, model_js_1.errorOnsetOf)(event) - base } : {}) } }));\n        return {\n            id: threadId,\n            name: `Codewhale runtime · ${threadName}`,\n            events: normalized,\n            duration: Math.max(1, normalized.reduce((m, e) => Math.max(m, e.endTime, e.startTime, e.status === 'error' ? (0, model_js_1.errorOnsetOf)(e) : 0), 0)),\n            originTime: origin !== undefined ? new Date(origin + base).toISOString() : '0 ms',\n            source: 'codewhale',\n            privacy: 'redact',\n            warnings: [...new Set(warnings)],\n            metadata: {\n                sourceFormat: 'codewhale.runtime-events/v2',\n                timeBasis: 'wall-clock',\n                sourceFilename: filename,\n                threadId,","sourceCodeStart":2464,"sourceCodeEnd":2500,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tui/pet_watch/pet-native.js#L2464-L2500","documentation":"Thrown by the Codewhale runtime trace importer in pet-native.js when, after parsing a runtime events file, no usable timeline events remain — the file only contained `item.delta` token-stream fragments and/or records that could not be correlated (unmatched item starts, requests without terminal receipts). The importer refuses to produce an empty trace because durations and spans would be meaningless.","triggerScenarios":"Calling `fromCodewhaleRuntime(records)` (or the trace load path that uses it) with a records array where every entry was either an `item.delta` stream fragment (all skipped during journaling) or unreadable/incomplete records, leaving `events.length === 0` at the end of the parse.","commonSituations":"Pointing the pet-watch trace viewer at a log captured mid-generation where only streamed deltas were flushed; a truncated or corrupted runtime file where all events failed journal correlation; an old/other-format file that the journal drops wholesale as 'unreadable records'.","solutions":["Verify you are loading a complete codewhale.runtime-events/v2 file that contains item start/end events, not only stream deltas.","Re-capture the runtime file, letting the session finish (or terminate cleanly) so item completion events and terminal receipts are written.","Check the file is not truncated (incomplete write/crash) — regenerate or restore from a known-good capture.","If you only have delta fragments, rebuild the capture from the session log where item start/end spans are recorded."],"exampleFix":"// before\nconst trace = fromCodewhaleRuntime(JSON.parse(fs.readFileSync('mid-generation.jsonl')));\n// after\nconst records = JSON.parse(fs.readFileSync('completed-session.runtime-events.jsonl'));\nif (!records.some(r => r.type === 'item.start' || r.type === 'item.end')) {\n  throw new Error('capture has no item spans; re-capture a completed session');\n}\nconst trace = fromCodewhaleRuntime(records);","handlingStrategy":"validation","validationCode":"const records = readRuntimeRecords(path);\nif (!records.some(r => /item\\.(start|end)/.test(r.type ?? ''))) {\n  throw new Error(`${path} has no item spans; cannot build a trace`);\n}","typeGuard":"function hasImportableEvents(records) {\n  return Array.isArray(records) && records.some(r => r && typeof r === 'object' && /^item\\.(start|end)$/.test(String(r.type)));\n}","tryCatchPattern":"try {\n  const trace = fromCodewhaleRuntime(records);\n} catch (e) {\n  if (e.message.includes('only stream deltas or unreadable records')) {\n    console.error('capture contains no usable spans; re-capture a completed session');\n  } else throw e;\n}","preventionTips":["Only import runtime files from completed sessions with item start/end events.","Check file integrity (non-truncated JSONL) before import.","Log the importer's warnings about dropped deltas and unmatched items.","Keep capture and import format versions in sync (codewhale.runtime-events/v2)."],"tags":["trace-import","empty-timeline","runtime-events"],"backgroundTag":"empty-required-field","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T11:17:16.035Z"}