{"record":{"id":"e1e7b55d1093270b","repo":"Hmbown/CodeWhale","slug":"runtime-import-cancelled-a-line-is-not-a-codewhale-runtime","errorCode":null,"errorMessage":"Runtime import cancelled: a line is not a Codewhale runtime event record. No rows were skipped.","messagePattern":"Runtime import cancelled: a line is not a Codewhale runtime event record\\. No rows were skipped\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/tui/pet_watch/pet-native.js","lineNumber":2310,"sourceCode":"    append(records) {\n        if (!records.length)\n            return;\n        const { events, open, requests } = this;\n        const threadId = this.threadId ?? str(obj(records[0]).thread_id) ?? this.filename;\n        this.threadId = threadId;\n        let { origin, model, skippedDeltas } = this;\n        let threadName = this.threadName ?? threadId;\n        const stamp = (rec) => {\n            const t = parseTime(rec.timestamp);\n            if (t === undefined)\n                throw new Error(`Runtime event seq ${rec.seq} is missing a usable timestamp.`);\n            if (origin === undefined)\n                origin = t;\n            return t - origin;\n        };\n        for (const raw of records) {\n            if (!isCodewhaleRuntimeRecord(raw))\n                throw new Error('Runtime import cancelled: a line is not a Codewhale runtime event record. No rows were skipped.');\n            this.recordCount++;\n            const rec = obj(raw);\n            if (rec.thread_id !== threadId)\n                throw new Error('Runtime import contains multiple threads. Export one thread before importing.');\n            const eventName = rec.event;\n            if (eventName === 'item.delta') {\n                skippedDeltas++;\n                continue;\n            }\n            const payload = obj(rec.payload);\n            const item = obj(payload.item);\n            const turn = obj(payload.turn);\n            const thread = obj(payload.thread);\n            const relative = stamp(rec);\n            const turnId = str(rec.turn_id) ?? str(payload.turn_id);\n            const itemId = str(rec.item_id) ?? str(item.id);\n            const agentId = 'parent';\n            if (str(thread.model))","sourceCodeStart":2292,"sourceCodeEnd":2328,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/tui/pet_watch/pet-native.js#L2292-L2328","documentation":"Every line of a runtime export must be a valid Codewhale runtime event record, checked by isCodewhaleRuntimeRecord. If any record fails the shape check, the whole import is cancelled with no rows skipped — the importer is all-or-nothing to avoid a silently partial timeline. The message deliberately states the abort semantics.","triggerScenarios":"Importing a runtime file containing a non-record line: a JSON header/footer object, a log line, a null, an array element, or a record missing required fields like seq/event/timestamp/thread_id.","commonSituations":"Concatenating exports from different versions; a partial/truncated last line; exporting stdout that mixes progress output with records; passing a JSON array instead of newline-delimited records.","solutions":["Inspect the runtime file and remove or fix lines that are not valid runtime records (check seq, event, timestamp, thread_id).","Re-export a single thread cleanly from Codewhale.","Validate each line with the same shape predicate before importing (see validation code).","Ensure the file is the newline-delimited record format, not wrapped JSON."],"exampleFix":"// before (mixed content)\n{\"note\":\"export started\"}\n{\"seq\":1,\"event\":\"item.completed\",\"thread_id\":\"t1\",\"timestamp\":\"...\"}\n// after\n{\"seq\":1,\"event\":\"item.completed\",\"thread_id\":\"t1\",\"timestamp\":\"...\"}","handlingStrategy":"validation","validationCode":"const isRecord = (r) => r && typeof r === 'object' && !Array.isArray(r) && Number.isFinite(r.seq) && typeof r.event === 'string' && typeof r.thread_id === 'string';\nif (!records.every(isRecord)) throw new Error('File contains non-record lines');","typeGuard":"const isCodewhaleRuntimeRecord = (v) => typeof v === 'object' && v !== null && 'seq' in v && 'event' in v && 'thread_id' in v;","tryCatchPattern":"try { importRuntime(lines); } catch (e) { if (e.message.includes('not a Codewhale runtime event record')) rejectWholeFile(lines); else throw e; }","preventionTips":["Validate every line before import; the import is all-or-nothing.","Never mix export output with logs or headers.","Confirm the file is newline-delimited records, not wrapped JSON.","Re-export cleanly instead of concatenating old exports."],"tags":["import","validation","format"],"backgroundTag":"schema-validation-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}