jackwener/OpenCLI · error · CommandExecutionError

${label} returned invalid JSON: ${outcome.detail}

Error message

${label} returned invalid JSON: ${outcome.detail}

What it means

postJikeApi expects every successful response to be JSON. When the response body cannot be parsed as JSON (kind 'json'), it throws CommandExecutionError with the parse error detail. This guards callers from receiving undefined/garbage data when the server returns HTML (login page, error page, WAF challenge) or an empty body.

Source

Thrown at clis/jike/utils.js:82

      let body;
      try {
        body = await response.json();
      } catch (error) {
        return { kind: 'json', status: response.status, detail: String(error?.message || error) };
      }
      return { kind: 'response', status: response.status, body };
    } catch (error) {
      return { kind: 'transport', detail: String(error?.message || error) };
    }
  })()`);
  if (outcome?.kind === 'auth' || outcome?.status === 401 || outcome?.status === 403) {
    throw new AuthRequiredError('web.okjike.com', outcome?.detail || `${label} returned HTTP ${outcome?.status}`);
  }
  if (outcome?.kind === 'transport') {
    throw new CommandExecutionError(`${label} request failed: ${outcome.detail}`);
  }
  if (outcome?.kind === 'json') {
    throw new CommandExecutionError(`${label} returned invalid JSON: ${outcome.detail}`);
  }
  if (outcome?.kind !== 'response' || !Number.isInteger(outcome.status)) {
    throw new CommandExecutionError(`${label} returned an unexpected response`);
  }
  if (outcome.status < 200 || outcome.status >= 300) {
    throw new CommandExecutionError(`${label} returned HTTP ${outcome.status}`);
  }
  return outcome.body;
}

/**
 * 注入浏览器 evaluate 的 JS 函数字符串。
 * 从 React fiber 树中向上最多走 10 层,找到含 id 字段的 props.data。
 */
export const getPostDataJs = `
function getPostData(element) {
  for (const key of Object.keys(element)) {
    if (key.startsWith('__reactFiber$') || key.startsWith('__reactInternalInstance$')) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-authenticate: run the site's auth/login flow so cookies are fresh and the server stops returning HTML pages
  2. Check outcome.detail in the message for the exact JSON parse error and inspect the raw body
  3. Confirm the endpoint still returns JSON (open it in a browser or with curl using the same cookies)
  4. Disable interfering proxies/VPN or anti-bot tooling that may inject challenge pages
  5. Retry later if it is a temporary WAF/CDN issue

Example fix

// before
const feed = await body('postJikeApi', '/api/feed');
// after
let feed;
try {
  feed = await body('postJikeApi', '/api/feed');
} catch (err) {
  if (/invalid JSON/.test(err.message)) {
    throw new AuthRequiredError('web.okjike.com', 'Session likely expired — re-run login flow');
  }
  throw err;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const res = await fetch('https://web.okjike.com/<endpoint>', { headers });
const text = await res.text();
try { JSON.parse(text); } catch { throw new Error('Endpoint returning non-JSON — re-login or check for WAF challenge'); }

Type guard

function isInvalidJsonError(err) {
  return err instanceof CommandExecutionError && /invalid JSON/.test(err.message);
}

Try / catch

try {
  const body = await body('postJikeApi', path, payload);
} catch (err) {
  if (isInvalidJsonError(err)) {
    // likely HTML login page or WAF challenge: trigger re-auth flow
  } else throw err;
}

Prevention

When it happens

Trigger: A request to web.okjike.com returns HTTP 200 but a non-JSON body: an HTML login/redirect page, a Cloudflare/WAF challenge page, an empty body, or a truncated response, so JSON.parse fails inside the fetch wrapper.

Common situations: Session cookies expired and the server returns an HTML login page with 200; site placed a bot-check/verification page; server returned an error page with wrong Content-Type; CDN interception.

Understand the failure class

Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.

Related errors


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