{"record":{"id":"f67a5a9dd789ca7b","repo":"pbakaus/impeccable","slug":"invalid-impeccable-live-copy-agent-mock-writes-jso","errorCode":null,"errorMessage":"Invalid IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES JSON","messagePattern":"Invalid IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES JSON","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"skill/scripts/live-copy-edit-agent.mjs","lineNumber":517,"sourceCode":"    const parsed = parseCopyEditBatchResult(raw);\n    if (parsed) return parsed;\n    throw new Error('Invalid IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT JSON');\n  }\n  return {\n    status: 'done',\n    appliedEntryIds: (batch?.entries || []).map((entry) => entry.id).filter(Boolean),\n    failed: [],\n    files: [],\n    notes: ['mock copy-edit batch result'],\n  };\n}\n\nfunction applyMockWrites(env, cwd) {\n  const raw = env.IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES;\n  if (!raw) return;\n  const writes = tryParseJson(raw);\n  if (!writes || typeof writes !== 'object' || Array.isArray(writes)) {\n    throw new Error('Invalid IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES JSON');\n  }\n  for (const [relativeFile, content] of Object.entries(writes)) {\n    if (typeof relativeFile !== 'string' || typeof content !== 'string') continue;\n    const absolute = path.resolve(cwd, relativeFile);\n    if (!isPathInsideOrEqual(cwd, absolute)) continue;\n    fs.mkdirSync(path.dirname(absolute), { recursive: true });\n    fs.writeFileSync(absolute, content, 'utf-8');\n  }\n}\n\nexport function parseCopyEditAgentResult(text) {\n  const trimmed = String(text || '').trim();\n  if (!trimmed) return null;\n\n  const parsedOuter = tryParseJson(trimmed);\n  if (parsedOuter) {\n    if (typeof parsedOuter.result === 'string') {\n      const nested = parseCopyEditAgentResult(parsedOuter.result);","sourceCodeStart":499,"sourceCodeEnd":535,"githubUrl":"https://github.com/pbakaus/impeccable/blob/d14711ae3d1a1dd62dee61a358d27f107c51ccd0/skill/scripts/live-copy-edit-agent.mjs#L499-L535","documentation":"Thrown by applyMockWrites() when IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES is set but does not parse into a plain object (it is JSON null, a primitive, or an array). The mock-writes var maps relative file paths to string contents that the mock runner writes under cwd; only an object map is meaningful.","triggerScenarios":"Setting IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES to a JSON array, a bare string, a number, or malformed JSON. Each entry's key and value must both be strings; non-string entries are skipped silently but a non-object top level throws.","commonSituations":"Building the writes map programmatically and serializing an array by mistake; quoting the JSON so it arrives as a stringified string rather than an object.","solutions":["Provide a JSON object mapping relative paths to string contents, e.g. {\"src/copy.txt\":\"Hello\"}.","Validate with `echo \"$IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES\" | jq 'type'` — it must report \"object\".","Unset the var if you do not need mock file writes."],"exampleFix":"// before\nexport IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES='[\"src/copy.txt\"]'\n// after\nexport IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES='{\"src/copy.txt\":\"Hello\"}'","handlingStrategy":"try-catch","validationCode":"function parseMockWrites(raw) {\n  if (!raw) return {};\n  let obj;\n  try { obj = JSON.parse(raw); } catch { throw new Error('IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES is not valid JSON'); }\n  if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {\n    throw new Error('mock writes must be a JSON object of path -> string');\n  }\n  return obj;\n}","typeGuard":"function isMockWritesObject(raw) {\n  if (!raw) return true;\n  try {\n    const o = JSON.parse(raw);\n    return o && typeof o === 'object' && !Array.isArray(o);\n  } catch { return false; }\n}","tryCatchPattern":"try {\n  const writes = JSON.parse(process.env.IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES);\n  if (Array.isArray(writes)) throw new Error('expected object');\n} catch (err) {\n  console.error('Fix IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES:', err.message);\n}","preventionTips":["Use jq to confirm the value is type \"object\".","Build the map in code and JSON.stringify it rather than hand-writing."],"tags":["live-copy-edit","mock","environment","json"],"backgroundTag":null,"analyzedSha":"d14711ae3d1a1dd62dee61a358d27f107c51ccd0","analyzedAt":"2026-08-13T00:52:25.771Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}