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

  1. Provide valid JSON with a status field, e.g. {"status":"done","appliedEntryIds":[],"failed":[],"files":[],"notes":[]}.
  2. Validate the JSON with `echo "$IMPECCABLE_LIVE_COPY_AGENT_MOCK_RESULT" | jq .` before starting the server.
  3. 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

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


AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13). Data as JSON: /api/errors/2a7e1ab3234988c5. Report an issue: GitHub.