{"record":{"id":"1892fd511576f3b8","repo":"jackwener/OpenCLI","slug":"invalid-jsonl-record-in-filepath-at-line-inde","errorCode":null,"errorMessage":"Invalid JSONL record in ${filePath} at line ${index + 1}: ${error instanceof Error ? error.message : String(error)}","messagePattern":"Invalid JSONL record in (.+?) at line (.+?): (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/archive.js","lineNumber":55,"sourceCode":"    if (!filePath || !fs.existsSync(filePath))\n        return { seen, count };\n    const text = fs.readFileSync(filePath, 'utf8');\n    for (const [index, line] of text.split('\\n').entries()) {\n        const trimmed = line.trim();\n        if (!trimmed)\n            continue;\n        try {\n            const row = JSON.parse(trimmed);\n            if (!row?.id)\n                throw new Error('missing id');\n            const id = String(row.id);\n            if (seen.has(id))\n                throw new Error(`duplicate id ${id}`);\n            seen.add(id);\n            count += 1;\n        }\n        catch (error) {\n            throw new CommandExecutionError(`Invalid JSONL record in ${filePath} at line ${index + 1}: ${error instanceof Error ? error.message : String(error)}`);\n        }\n    }\n    return { seen, count };\n}\n\nexport function appendJsonlRows(filePath, rows) {\n    if (!filePath || !Array.isArray(rows) || rows.length === 0)\n        return;\n    ensureParentDir(filePath);\n    // Escape LS/PS so JSONL stays one physical line even when tweet text contains them.\n    const text = rows\n        .map((row) => JSON.stringify(row).replace(/\\u2028/g, '\\\\u2028').replace(/\\u2029/g, '\\\\u2029'))\n        .join('\\n') + '\\n';\n    fs.appendFileSync(filePath, text, 'utf8');\n}\n\nexport function removeResumeFile(filePath) {\n    removeFile(filePath);","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/archive.js#L37-L73","documentation":"loadJsonlArchiveState reads a JSONL file line by line; each record must parse and contain a valid, non-duplicate id. Any per-line failure (JSON syntax error, missing id, duplicate id) is rethrown as a CommandExecutionError naming the file, the 1-based line number, and the underlying cause. This pinpoints exactly which archive line is corrupt so resume state can be repaired.","triggerScenarios":"The resume/state JSONL file contains a line that fails JSON.parse, lacks an id field, or repeats an id already seen — thrown from the state or jsonlState commands.","commonSituations":"Manually editing the JSONL file and breaking syntax, a previous run being killed mid-write leaving a truncated last line, file corruption from disk issues, or concatenating two archive files producing duplicate ids.","solutions":["Open the file at the reported line number and fix or delete the malformed record","If the last line is truncated (killed process), remove just that partial line — earlier records remain valid","Deduplicate repeated id lines or restore the file from a backup","If untrusted, delete the state file and rerun so a fresh archive is written"],"exampleFix":"// before (corrupt line 3)\n{\"id\":\"12\"}\n{\"id\":\"13\"\n// after (truncated line removed)\n{\"id\":\"12\"}\n{\"id\":\"13\"}","handlingStrategy":"validation","validationCode":"import { readFileSync } from 'node:fs';\nfunction validateJsonl(filePath) {\n  const seen = new Set();\n  readFileSync(filePath, 'utf8').split('\\n').forEach((line, i) => {\n    if (!line.trim()) return;\n    const rec = JSON.parse(line); // throws with line info on corrupt data\n    if (seen.has(rec.id)) throw new Error(`duplicate id ${rec.id} at line ${i + 1}`);\n    seen.add(rec.id);\n  });\n}","typeGuard":"function isValidRecord(rec) { return rec !== null && typeof rec === 'object' && typeof rec.id === 'string' && rec.id.length > 0; }","tryCatchPattern":"try {\n  const state = await loadJsonlArchiveState(filePath);\n} catch (err) {\n  const m = /line (\\d+)/.exec(err.message);\n  if (m) console.error(`Fix or delete line ${m[1]} of ${filePath}, then rerun`);\n  else throw err;\n}","preventionTips":["Don't hand-edit JSONL state files; if needed, validate after each edit","Remove truncated trailing lines after a killed run","Back up state files before manual repair","Deduplicate ids when merging archives"],"tags":["json","jsonl","parsing","state"],"backgroundTag":"malformed-jsonl-record","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}