pbakaus/impeccable · error · Error
Invalid IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT JSON
Error message
Invalid IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT JSON
What it means
Thrown by mockBatchResult() in skill/scripts/live-copy-edit-agent.mjs when IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT is set but its value does not parse (via parseCopyEditBatchResult) into a valid batch result object. The mock runner is the test/dev path (IMPECCABLE_LIVE_COPY_AGENT=mock); an invalid override breaks the mock contract.
Source
Thrown at skill/scripts/live-copy-edit-agent.mjs:501
: [];
return {
status,
message: result.message || null,
appliedEntryIds,
failed,
files,
notes,
warnings,
};
}
function mockBatchResult(batch, env, cwd = process.cwd()) {
applyMockWrites(env, cwd);
const raw = env.IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT;
if (raw) {
const parsed = parseCopyEditBatchResult(raw);
if (parsed) return parsed;
throw new Error('Invalid IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT JSON');
}
return {
status: 'done',
appliedEntryIds: (batch?.entries || []).map((entry) => entry.id).filter(Boolean),
failed: [],
files: [],
notes: ['mock copy-edit batch result'],
};
}
function applyMockWrites(env, cwd) {
const raw = env.IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES;
if (!raw) return;
const writes = tryParseJson(raw);
if (!writes || typeof writes !== 'object' || Array.isArray(writes)) {
throw new Error('Invalid IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES JSON');
}
for (const [relativeFile, content] of Object.entries(writes)) {View on GitHub (pinned to d14711ae3d)
Solutions
- Provide valid JSON with a status field, e.g. {"status":"done","appliedEntryIds":[],"failed":[],"files":[],"notes":[]}.
- Validate the JSON with `echo "$IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT" | jq .` before starting the server.
- Unset the var to fall back to the default mock result.
Example fix
// before
export IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT='{status: done}'
// after
export IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT='{"status":"done","appliedEntryIds":[],"failed":[],"files":[],"notes":[]}' Defensive patterns
Strategy: try-catch
Validate before calling
function parseMockResult(raw) {
if (!raw) return null;
let obj;
try { obj = JSON.parse(raw); } catch { throw new Error('IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT is not valid JSON'); }
if (!['done', 'partial', 'error'].includes(obj?.status)) {
throw new Error('mock result needs a status of done|partial|error');
}
return obj;
} Type guard
function isValidMockResultJson(raw) {
if (!raw) return true;
try {
const o = JSON.parse(raw);
return o && ['done', 'partial', 'error'].includes(o.status);
} catch { return false; }
} Try / catch
try {
JSON.parse(process.env.IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT);
} catch (err) {
console.error('Fix or unset IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT:', err.message);
process.exit(1);
} Prevention
- Validate mock env JSON with jq before starting the server.
- Keep a known-good mock result committed for tests.
When it happens
Trigger: Setting IMPECCABLE_LIVE_COPY_AGENT=mock and IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT to malformed JSON, or to JSON missing the required `status` field (must be 'done' | 'partial' | 'error').
Common situations: Hand-editing the mock result env var and breaking the JSON; pasting a partial object; quoting issues in the shell mangling the value.
Related errors
- Invalid IMPECCABLE_LIVE_COPY_AGENT_MOCK_WRITES JSON
- No live copy-edit AI runner is available.
- No live copy-edit AI runner is available.
- Unsupported live copy-edit AI runner: ${provider}
- AI copy-edit batch did not return a valid completion payload
AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13).
Data as JSON: /api/errors/2a7e1ab3234988c5.
Report an issue: GitHub.