Hmbown/CodeWhale · error · Error
Runtime event seq is missing a usable timestamp.
Error message
Runtime event seq ${rec.seq} is missing a usable timestamp. What it means
Each runtime record must carry a parseable timestamp; stamp() converts rec.timestamp into a relative event time using the first record as origin. If parseTime cannot interpret the timestamp, the import aborts with the offending record's seq so the bad row can be located. Without a timestamp the event cannot be placed on the timeline.
Solutions
- Locate the record with the reported seq in the runtime export and fix or remove its timestamp.
- Re-export the runtime stream with a compatible Codewhale version.
- Validate all timestamps parse before import (see validation code).
- If hand-editing, use ISO 8601 (e.g. 2026-09-21T12:00:00.000Z).
Example fix
// before (record in export)
{ "seq": 7, "event": "item.completed", "timestamp": "yesterday" }
// after
{ "seq": 7, "event": "item.completed", "timestamp": "2026-09-21T12:00:00.000Z" } Defensive patterns
Strategy: validation
Validate before calling
const badSeq = records.find(r => !Number.isFinite(Date.parse(r?.timestamp)));
if (badSeq) throw new Error(`Record seq ${badSeq.seq} has an unusable timestamp`); Type guard
const hasTimestamp = (r) => typeof r?.timestamp === 'string' && !Number.isNaN(Date.parse(r.timestamp));
Try / catch
try { importRuntime(records); } catch (e) { if (e.message.includes('missing a usable timestamp')) quarantineRecordBySeq(e); else throw e; } Prevention
- Validate all timestamps parse before import.
- Use ISO 8601 timestamps in exports.
- Don't hand-edit timestamp fields.
- Re-export after version upgrades rather than patching files.
When it happens
Trigger: Importing a runtime export containing a record whose timestamp field is missing, null, empty, or in a format parseTime does not recognize (e.g. non-ISO string, integer seconds vs ms mismatch handled elsewhere).
Common situations: Hand-edited exports; exports from a different Codewhale version with a changed timestamp format; clock skew/corruption writing 'undefined' or partial timestamps; truncated JSON lines.
Related errors
- bundle contains conflicting or rejected entries
- Choose one recording to import.
- Codewhale runtime event file is empty.
- Duplicate producer incarnation/sequence in evidence bundle…
- import source must be a compatible external skill
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/8d13f0a593f5b516.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/pet_watch/pet-native.js:2303
this.sizes.delete(event);
if (this.open.get(event.id) === event)
this.open.delete(event.id);
}
}
this.events.length = keep;
}
append(records) {
if (!records.length)
return;
const { events, open, requests } = this;
const threadId = this.threadId ?? str(obj(records[0]).thread_id) ?? this.filename;
this.threadId = threadId;
let { origin, model, skippedDeltas } = this;
let threadName = this.threadName ?? threadId;
const stamp = (rec) => {
const t = parseTime(rec.timestamp);
if (t === undefined)
throw new Error(`Runtime event seq ${rec.seq} is missing a usable timestamp.`);
if (origin === undefined)
origin = t;
return t - origin;
};
for (const raw of records) {
if (!isCodewhaleRuntimeRecord(raw))
throw new Error('Runtime import cancelled: a line is not a Codewhale runtime event record. No rows were skipped.');
this.recordCount++;
const rec = obj(raw);
if (rec.thread_id !== threadId)
throw new Error('Runtime import contains multiple threads. Export one thread before importing.');
const eventName = rec.event;
if (eventName === 'item.delta') {
skippedDeltas++;
continue;
}
const payload = obj(rec.payload);
const item = obj(payload.item);View on GitHub (pinned to 73e0f67d83)