{"record":{"id":"76602c5f2a5e722d","repo":"pbakaus/impeccable","slug":"manual-edit-buffer-invalid-schema","errorCode":null,"errorMessage":"manual_edit_buffer_invalid_schema","messagePattern":"manual_edit_buffer_invalid_schema","errorType":"exception","errorClass":null,"httpStatus":500,"severity":"error","filePath":"skill/scripts/live/manual-edits-buffer.mjs","lineNumber":38,"sourceCode":"export function getBufferPath(cwd = process.cwd()) {\n  return path.join(getLiveDir(cwd), BUFFER_FILENAME);\n}\n\nexport function readBuffer(cwd = process.cwd()) {\n  return readBufferInternal(cwd, { strict: false });\n}\n\nexport function readBufferStrict(cwd = process.cwd()) {\n  return readBufferInternal(cwd, { strict: true });\n}\n\nfunction readBufferInternal(cwd, { strict }) {\n  const filePath = getBufferPath(cwd);\n  try {\n    const raw = fs.readFileSync(filePath, 'utf-8');\n    const parsed = JSON.parse(raw);\n    if (!parsed || typeof parsed !== 'object' || !Array.isArray(parsed.entries)) {\n      if (strict) throw new Error('manual_edit_buffer_invalid_schema');\n      return { version: BUFFER_VERSION, entries: [] };\n    }\n    return { version: BUFFER_VERSION, entries: parsed.entries };\n  } catch (err) {\n    if (strict && err?.code !== 'ENOENT') {\n      throw new Error('manual_edit_buffer_unreadable: ' + (err.message || String(err)));\n    }\n    return { version: BUFFER_VERSION, entries: [] };\n  }\n}\n\nexport function writeBuffer(cwd, buffer) {\n  const filePath = getBufferPath(cwd);\n  fs.mkdirSync(path.dirname(filePath), { recursive: true });\n  fs.writeFileSync(filePath, JSON.stringify({ version: BUFFER_VERSION, entries: buffer.entries }, null, 2));\n}\n\n/**","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/pbakaus/impeccable/blob/f88b2837a7d7c3182e46307bbbb091a1ed547571/skill/scripts/live/manual-edits-buffer.mjs#L20-L56","documentation":"readBufferStrict() (skill/scripts/live/manual-edits-buffer.mjs) reads the pending-manual-edits buffer at .impeccable/live/pending-manual-edits.json. The file parsed as valid JSON, but the root is not an object or parsed.entries is not an array — i.e. the shape { version: 1, entries: [...] } is violated. Strict readers (the apply/commit path) throw manual_edit_buffer_invalid_schema; lenient readers (readBuffer) silently reset to an empty buffer instead.","triggerScenarios":"The buffer file was hand-edited or written in a different format: root is an array of entries, entries was renamed, or the whole staged-edit structure from an older/newer skill version is present.","commonSituations":"An agent editing the buffer directly instead of going through the browser Save path; skill upgrades that changed the buffer schema; hand-resolved merge conflicts on the file.","solutions":["Inspect .impeccable/live/pending-manual-edits.json","Rewrite it as { \"version\": 1, \"entries\": [ ... ] }, preserving the staged entries if they are recoverable","Otherwise archive/delete the file to start a clean buffer — staged browser edits recorded in it are discarded and must be re-made"],"exampleFix":"// .impeccable/live/pending-manual-edits.json — before\n[ { \"id\": \"e1\", \"text\": \"...\" } ]\n\n// after\n{ \"version\": 1, \"entries\": [ { \"id\": \"e1\", \"text\": \"...\" } ] }","handlingStrategy":"type-guard","validationCode":"import fs from 'node:fs';\n\nconst p = '.impeccable/live/pending-manual-edits.json';\nif (fs.existsSync(p)) {\n  const parsed = JSON.parse(fs.readFileSync(p, 'utf-8'));\n  if (!parsed || typeof parsed !== 'object' || !Array.isArray(parsed.entries)) {\n    throw new Error('buffer schema drifted — archive the file and re-stage edits');\n  }\n}","typeGuard":"const isValidEditBuffer = (v) =>\n  !!v && typeof v === 'object' && !Array.isArray(v) && Array.isArray(v.entries);","tryCatchPattern":"try {\n  buffer = readBufferStrict(cwd);\n} catch (err) {\n  if (err?.message === 'manual_edit_buffer_invalid_schema') {\n    // Reset path: archive the drifted buffer, accept that staged edits are lost,\n    // re-stage via the browser Save flow.\n    fs.renameSync(bufferPath, bufferPath + '.invalid');\n    buffer = { version: 1, entries: [] };\n  } else {\n    throw err;\n  }\n}","preventionTips":["Never hand-edit pending-manual-edits.json — stage edits through the browser Save path","Treat buffer schema changes as migration points: transform old shapes on skill upgrade instead of keeping them","Archive (rename) rather than delete drifted buffers so staged content stays inspectable"],"tags":["json","buffer","schema","manual-edits"],"backgroundTag":"invalid-json-structure","analyzedSha":"f88b2837a7d7c3182e46307bbbb091a1ed547571","analyzedAt":"2026-08-18T04:58:36.608Z","contentChangedAt":"2026-08-18T04:58:36.608Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}