Hmbown/CodeWhale · error · Error
Runtime import cancelled: a line is not a Codewhale runtime…
Error message
Runtime import cancelled: a line is not a Codewhale runtime event record. No rows were skipped.
What it means
Thrown at the start of the runtime record loop when a parsed line fails isCodewhaleRuntimeRecord(), i.e. it does not have the shape of a Codewhale runtime event record. The import is deliberately cancelled with no rows skipped: the library refuses to partially import a file that is not cleanly a runtime export. This protects against importing the wrong file or a corrupted one.
Solutions
- Confirm you are importing a Codewhale runtime export (JSONL of runtime event records), not a session snapshot or other file.
- Find and inspect the first invalid line (check for truncated/partial JSON from an interrupted export).
- Re-export the thread and re-import the fresh file.
- Pre-validate all lines with the same record shape check before feeding the importer.
Example fix
// before
runtime.feed(threadId, text.split('\n').map(l => JSON.parse(l)));
// after
const records = text.split('\n').filter(Boolean).map(l => JSON.parse(l));
const bad = records.findIndex(r => !isCodewhaleRuntimeRecord(r));
if (bad >= 0) throw new Error(`Line ${bad + 1} is not a runtime record`);
const events = runtime.feed(threadId, records); Defensive patterns
Strategy: type-guard
Validate before calling
const badIndex = records.findIndex(r => !isCodewhaleRuntimeRecord(r));
if (badIndex >= 0) throw new Error(`Line ${badIndex + 1} is not a Codewhale runtime record; wrong or corrupt file?`); Type guard
function isRuntimeRecordFile(records) {
return Array.isArray(records) && records.length > 0 && records.every(isCodewhaleRuntimeRecord);
} Try / catch
try {
runtime.import(text, threadId);
} catch (e) {
if (String(e.message).includes('not a Codewhale runtime event record')) {
console.error('File rejected wholesale: verify it is a runtime export and not truncated.');
} else throw e;
} Prevention
- Confirm the file type before import (runtime export vs session snapshot).
- Validate every line's record shape before importing.
- Handle truncated last lines from interrupted exports.
- Pin importer/exporter versions together.
When it happens
Trigger: Importing a runtime file where at least one record lacks the required runtime-record shape (missing seq/event/thread fields, wrong types) so isCodewhaleRuntimeRecord(raw) returns false at pet/ios/Resources/pet-native.js:2310. Happens on the first bad line.
Common situations: Pointing the importer at the wrong file (session snapshot, logs, or another JSONL); a truncated final line from an interrupted export; hand-merged files mixing record kinds; schema drift after a Codewhale version update.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Runtime import cancelled: a line is not a Codewhale runtime…
- bundle contains conflicting or rejected entries
- Choose one recording to import.
- Codewhale runtime event file is empty.
- CRON field contains an empty list item
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/f198a9ef6874bdbc.
Report an issue: GitHub.
Appendix: source
Thrown at pet/ios/Resources/pet-native.js:2310
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);
const turn = obj(payload.turn);
const thread = obj(payload.thread);
const relative = stamp(rec);
const turnId = str(rec.turn_id) ?? str(payload.turn_id);
const itemId = str(rec.item_id) ?? str(item.id);
const agentId = 'parent';
if (str(thread.model))View on GitHub (pinned to 433685b202)