Hmbown/CodeWhale · error · Error
Codewhale runtime file contained only stream deltas or…
Error message
Codewhale runtime file contained only stream deltas or unreadable records.
What it means
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.
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.
Example fix
// before
const trace = fromCodewhaleRuntime(JSON.parse(fs.readFileSync('mid-generation.jsonl')));
// after
const records = JSON.parse(fs.readFileSync('completed-session.runtime-events.jsonl'));
if (!records.some(r => r.type === 'item.start' || r.type === 'item.end')) {
throw new Error('capture has no item spans; re-capture a completed session');
}
const trace = fromCodewhaleRuntime(records); Defensive patterns
Strategy: validation
Validate before calling
const records = readRuntimeRecords(path);
if (!records.some(r => /item\.(start|end)/.test(r.type ?? ''))) {
throw new Error(`${path} has no item spans; cannot build a trace`);
} Type guard
function hasImportableEvents(records) {
return Array.isArray(records) && records.some(r => r && typeof r === 'object' && /^item\.(start|end)$/.test(String(r.type)));
} Try / catch
try {
const trace = fromCodewhaleRuntime(records);
} catch (e) {
if (e.message.includes('only stream deltas or unreadable records')) {
console.error('capture contains no usable spans; re-capture a completed session');
} else throw e;
} Prevention
- 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).
When it happens
Trigger: 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.
Common situations: 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'.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Codewhale runtime event file is empty.
- Codewhale runtime event file is empty.
- Invalid Runtime observation horizon.
- Runtime import contains multiple threads. Export one thread…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/e6852eea8f21fe66.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/pet_watch/pet-native.js:2482
});
}
this.origin = origin;
this.model = model;
this.threadName = threadName;
this.skippedDeltas = skippedDeltas;
}
snapshot() {
const { events, open, requests, origin, model, skippedDeltas, filename } = this;
const threadId = this.threadId ?? filename, threadName = this.threadName ?? threadId;
const warnings = [];
if (skippedDeltas)
warnings.push(`Dropped ${skippedDeltas.toLocaleString()} item.delta records; they are token stream fragments, not spans. Item start/end remain the source of duration.`);
for (const [id] of open)
warnings.push(`Item ${id} started and never completed in this file; duration remains unknown.`);
for (const request of requests.values())
warnings.push(`Request ${request.id} has no terminal receipt; its duration remains unknown in this file.`);
if (!events.length)
throw new Error('Codewhale runtime file contained only stream deltas or unreadable records.');
const base = events.reduce((m, e) => Math.min(m, e.startTime), events[0].startTime);
const normalized = events.map(event => ({ ...event, startTime: event.startTime - base, endTime: event.endTime - base,
attributes: { ...event.attributes, ...(event.attributes['whalesong.error_onset_ms'] !== undefined
? { 'whalesong.error_onset_ms': (0, model_js_1.errorOnsetOf)(event) - base } : {}) } }));
return {
id: threadId,
name: `Codewhale runtime · ${threadName}`,
events: normalized,
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)),
originTime: origin !== undefined ? new Date(origin + base).toISOString() : '0 ms',
source: 'codewhale',
privacy: 'redact',
warnings: [...new Set(warnings)],
metadata: {
sourceFormat: 'codewhale.runtime-events/v2',
timeBasis: 'wall-clock',
sourceFilename: filename,
threadId,View on GitHub (pinned to 73e0f67d83)