jackwener/OpenCLI · error · CliError

PARSE_ERROR

PARSE_ERROR

Error message

Invalid ZSXQ API response

What it means

unwrapRespData validates the shape of a ZSXQ API JSON payload before extracting resp_data. If the payload is not a plain object (asRecord returns null), it throws CliError PARSE_ERROR 'Invalid ZSXQ API response'. The library throws this because it cannot safely read succeeded/code/resp_data from a non-object payload.

Source

Thrown at clis/zsxq/utils.js:136

}
export async function fetchFirstJson(page, paths) {
    let lastFailure = null;
    for (const path of paths) {
        const result = await browserJsonRequest(page, path);
        if (result.ok) {
            return result;
        }
        lastFailure = result;
    }
    if (!lastFailure) {
        throw new CliError('FETCH_ERROR', 'No candidate endpoint returned JSON', `Checked endpoints: ${paths.join(', ')}`);
    }
    throw new CliError('FETCH_ERROR', lastFailure.error || 'Failed to fetch ZSXQ API', `Checked endpoints: ${paths.join(', ')}`);
}
export function unwrapRespData(payload) {
    const record = asRecord(payload);
    if (!record) {
        throw new CliError('PARSE_ERROR', 'Invalid ZSXQ API response');
    }
    if (record.succeeded === false) {
        const code = typeof record.code === 'number' ? String(record.code) : 'API_ERROR';
        const message = typeof record.info === 'string'
            ? record.info
            : typeof record.error === 'string'
                ? record.error
                : 'ZSXQ API returned an error';
        throw new CliError(code, message);
    }
    return (record.resp_data ?? record.data ?? payload);
}
export function getTopicsFromResponse(payload) {
    const data = unwrapRespData(payload);
    if (Array.isArray(data))
        return data;
    return pickArray(data.topics, data.list, data.records, data.items, data.search_result);
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log the raw payload before unwrapping to see the actual response shape
  2. Re-run with a fresh authenticated request — a stale/cached HTML-to-JSON artifact is common
  3. Update the library if ZSXQ changed its response envelope (succeeded/code/resp_data)

Example fix

// before
const data = unwrapRespData(payload);
// after
const record = payload && typeof payload === 'object' && !Array.isArray(payload) ? payload : null;
if (!record) throw new Error('unexpected payload: ' + JSON.stringify(payload).slice(0, 200));
const data = unwrapRespData(record);
Defensive patterns

Strategy: type-guard

Validate before calling

const isRecord = (p) => !!p && typeof p === 'object' && !Array.isArray(p);
if (!isRecord(payload)) throw new Error('Non-object ZSXQ payload: ' + JSON.stringify(payload).slice(0, 200));

Type guard

function isApiRecord(p) {
  return typeof p === 'object' && p !== null && !Array.isArray(p);
}

Try / catch

try {
  const data = unwrapRespData(payload);
} catch (e) {
  if (e.code === 'PARSE_ERROR') console.error('Unexpected ZSXQ payload shape', payload);
  else throw e;
}

Prevention

When it happens

Trigger: Calling data() (which routes through unwrapRespData) when the endpoint returned JSON that is not an object — e.g. an array, a string, or null payload from an unexpected response.

Common situations: API contract change returning a different JSON envelope; a proxy returning JSON like "ok" or [1,2]; a mocked/captured response reused incorrectly; CDN or WAF returning an error page that happens to parse as JSON.

Related errors


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