jackwener/OpenCLI · error · CommandExecutionError

${command} returned a malformed rows payload

Error message

${command} returned a malformed rows payload

What it means

requireRows requires payload.rows to be an array once the payload claims ok:true. This CommandExecutionError is thrown when rows is missing or of the wrong type, meaning the browser command reported success but returned an inconsistent result object.

Source

Thrown at clis/dribbble/utils.js:79

    }
    const match = url.pathname.match(/^\/shots\/(\d+)(?:-|\/|$)/);
    if (!match) throw new ArgumentError('shot URL must match dribbble.com/shots/<id>');
    return match[1];
}

export function requireRows(payload, command) {
    if (!payload || typeof payload !== 'object') {
        throw new CommandExecutionError(`${command} returned an unreadable browser payload`);
    }
    if (payload.empty) {
        throw new EmptyResultError(command, payload.reason || `${command} returned no results`);
    }
    if (!payload.ok) {
        const reason = payload.reason ? `: ${payload.reason}` : '';
        throw new CommandExecutionError(`${command} selector drift${reason}`);
    }
    if (!Array.isArray(payload.rows)) {
        throw new CommandExecutionError(`${command} returned a malformed rows payload`);
    }
    if (payload.rows.length === 0) {
        throw new EmptyResultError(command, `${command} page loaded but no matching rows were found`);
    }
    return payload.rows;
}

export function requireRow(payload, command) {
    if (!payload || typeof payload !== 'object') {
        throw new CommandExecutionError(`${command} returned an unreadable browser payload`);
    }
    if (payload.empty) {
        throw new EmptyResultError(command, payload.reason || `${command} was not found`);
    }
    if (!payload.ok || !payload.row) {
        const reason = payload.reason ? `: ${payload.reason}` : '';
        throw new CommandExecutionError(`${command} selector drift${reason}`);
    }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Ensure the browser command always returns rows as an array (even an empty one) when ok is true.
  2. Reinstall/align the library versions so the command scripts and utils match.
  3. When constructing payloads manually (tests, mocks), include rows: [] rather than omitting the field.

Example fix

// before
return { ok: true, reason: null }; // rows missing

// after
return { ok: true, reason: null, rows: [] };
Defensive patterns

Strategy: type-guard

Validate before calling

if (payload && payload.ok && !Array.isArray(payload.rows)) {
  throw new Error('payload.ok is true but rows is not an array');
}

Type guard

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

Try / catch

try {
  rows = requireRows(payload, 'shots');
} catch (e) {
  if (e instanceof CommandExecutionError && /malformed rows payload/.test(e.message)) {
    console.error('Browser command returned ok without a rows array; check command script version/shape');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: A modified or outdated browser command script that sets ok but returns rows as an object/null; a serialization step that dropped or reshaped the rows field; passing a hand-crafted payload into requireRows with rows omitted.

Common situations: Patching or wrapping the scraper's browser commands and accidentally changing the return shape, version mismatch between the CLI wrapper and browser scripts, or building payloads in tests without the rows key.

Understand the failure class

Related errors


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