jackwener/OpenCLI · error · Error

JSON parse failed (status=${r.status}, body[0..50]=${JSON.st

Error message

JSON parse failed (status=${r.status}, body[0..50]=${JSON.stringify(trimmed.slice(0, 50))}): ${(err && err.message ? err.message : String(err))}

What it means

This is the browser-side twin of the JSON parse guard: injected script code (embedded in a template string in src/utils.ts) that, after a fetch where r.ok, JSON.parses the text and on failure throws an Error with the status, a 50-char body preview, and the parser message. It surfaces malformed JSON to the Node side with enough context to debug without re-running in the browser.

Source

Thrown at src/utils.ts:206

  const looksLikeHtml =
    contentType.toLowerCase().includes('text/html')
    || /^<(?:!doctype|html|head|body|title)(?:[\\s>/]|$)/i.test(trimmed);
  if (looksLikeHtml) {
    return {
      __loginWall: true,
      status: r.status,
      url: r.url || (typeof input === 'string' ? input : ''),
      contentType,
      bodyPreview: trimmed.slice(0, 100),
    };
  }
  if (!r.ok) {
    return { error: r.status };
  }
  try {
    return JSON.parse(text);
  } catch (err) {
    throw new Error(
      'JSON parse failed (status=' + r.status + ', body[0..50]=' + JSON.stringify(trimmed.slice(0, 50)) + '): '
      + (err && err.message ? err.message : String(err))
    );
  }
}
`;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use the body[0..50] preview in the message to identify the actual payload
  2. Retry the in-page fetch; transient truncation is the most common cause
  3. Verify the endpoint URL is correct in the page context (relative URLs resolve against the page origin)
  4. Trim a leading BOM (\uFEFF) from the text before JSON.parse if previews show it

Example fix

// before
const data = JSON.parse(text);
// after
const clean = text.replace(/^\uFEFF/, '').trim();
const data = JSON.parse(clean || 'null');
Defensive patterns

Strategy: retry

Validate before calling

// Inside the injected script, before parsing:
const clean = text.replace(/^\uFEFF/, '').trim();
if (!clean) return { error: r.status, body: '' };

Try / catch

try {
  const data = await page.evaluate(script, url);
} catch (e) {
  if (/JSON parse failed/.test(String(e.message))) { console.error('In-page JSON malformed — retry or log body preview'); }
  throw e;
}

Prevention

When it happens

Trigger: Running injected fetch/parse code inside page.evaluate against an endpoint that returns r.ok but a body JSON.parse cannot handle (empty body, HTML that escaped the earlier check, truncated JSON).

Common situations: Page context fetches to endpoints behind experiments returning empty 200s; SPA dev servers intercepting API routes; responses cut off by browser network conditions; endpoints emitting BOM or non-UTF8 bytes.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/02908659079054da. Report an issue: GitHub.