jackwener/OpenCLI · error · CommandExecutionError

${label} returned malformed data

Error message

${label} returned malformed data

What it means

fetchNowcoderData requires payload.data to be a plain object (isRecord) even when success is true. If the Nowcoder API reports success but data is missing, null, or not an object, this CommandExecutionError is thrown. It guards downstream code from destructuring an undefined data field.

Source

Thrown at clis/nowcoder/posts.js:259

        await page.goto('https://www.nowcoder.com');
        payload = await page.fetchJson(url, options);
    }
    catch (error) {
        const detail = String(error?.message ?? error);
        if (/HTTP\s+(401|403)|need login|not logged in/i.test(detail)) {
            throw new AuthRequiredError('nowcoder.com', `${label} requires a logged-in Nowcoder session`);
        }
        throw new CommandExecutionError(`${label} failed: ${detail}`);
    }
    if (!isRecord(payload) || typeof payload.success !== 'boolean' || !Number.isSafeInteger(payload.code)) throw new CommandExecutionError(`${label} returned a malformed envelope`);
    const message = typeof payload.msg === 'string' ? payload.msg : 'unknown error';
    if (!payload.success || payload.code !== 0) {
        if (payload.code === 999 || /need login|登录/i.test(message)) {
            throw new AuthRequiredError('nowcoder.com', `${label} requires a logged-in Nowcoder session: ${message}`);
        }
        throw new CommandExecutionError(`${label} failed: ${message} (${payload.code})`);
    }
    if (!isRecord(payload.data)) throw new CommandExecutionError(`${label} returned malformed data`);
    return payload.data;
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check whether the query legitimately has no results and treat it as empty instead of an error
  2. Re-run with different parameters (narrower query, smaller pageSize)
  3. Verify the endpoint response shape with a raw request; if Nowcoder changed the schema, update the CLI parser
  4. Wrap the call in try/catch and fall back to an empty result set when appropriate

Example fix

// before
const data = await fetchNowcoderData(page, url, opts);
render(data.list);
// after
let data;
try { data = await fetchNowcoderData(page, url, opts); }
catch (e) { if (/malformed data/.test(e.message)) data = { list: [] }; else throw e; }
render(data.list);
Defensive patterns

Strategy: type-guard

Validate before calling

function hasData(env){ return isEnvelope(env) && env.success === true && env.code === 0 && env.data !== null && typeof env.data === 'object' && !Array.isArray(env.data); }

Type guard

function isRecord(v){ return v !== null && typeof v === 'object' && !Array.isArray(v); }
function hasPayloadData(env){ return isRecord(env) && isRecord(env.data); }

Try / catch

try { const data = await fetchNowcoderData(page, url, opts); }
catch (e) {
  if (e instanceof CommandExecutionError && e.message.includes('malformed data')) return emptyResult;
  throw e;
}

Prevention

When it happens

Trigger: A successful envelope ({ success:true, code:0 }) whose data field is null/undefined/an array/primitive — e.g. endpoints that return data:null when there are no results or when the API contract changed.

Common situations: Empty result sets where the API returns success:true with data:null; Nowcoder schema changes replacing the data object with something else; caching/CDN layers returning trimmed bodies.

Understand the failure class

Related errors


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