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

  1. Confirm you are importing a Codewhale runtime export (JSONL of runtime event records), not a session snapshot or other file.
  2. Find and inspect the first invalid line (check for truncated/partial JSON from an interrupted export).
  3. Re-export the thread and re-import the fresh file.
  4. 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

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


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)