jackwener/OpenCLI · error · CommandExecutionError

Douyin search: evaluator returned malformed cards payload

Error message

Douyin search: evaluator returned malformed cards payload

What it means

CommandExecutionError thrown when the evaluator returned an object with a valid state (e.g. 'ok') but result.cards is not an array. This indicates the in-page extraction script and the Node-side contract have drifted — the payload shape changed between the browser script and the adapter's validation.

Source

Thrown at clis/douyin/search.js:294

            throw new CommandExecutionError(`Douyin search extraction failed: ${error instanceof Error ? error.message : String(error)}`);
        }
        if (!result || typeof result !== 'object') {
            throw new CommandExecutionError('Douyin search: unexpected evaluator payload shape');
        }
        if (result.state === 'login_wall') {
            throw new AuthRequiredError(
                'www.douyin.com',
                'Douyin search results are blocked behind a login wall — log in at https://www.douyin.com in Chrome first.',
            );
        }
        if (result.state === 'empty') {
            throw new EmptyResultError('douyin search', `No Douyin videos matched "${keyword}".`);
        }
        if (result.state === 'timeout') {
            throw new CommandExecutionError('Douyin search did not render result cards within the timeout. Open the same search in Chrome and verify login/security state before retrying.');
        }
        if (!Array.isArray(result.cards)) {
            throw new CommandExecutionError('Douyin search: evaluator returned malformed cards payload');
        }
        if (result.cards.length === 0) {
            throw new EmptyResultError('douyin search', `No Douyin videos matched "${keyword}".`);
        }
        const projected = projectSearchCards(result.cards, limit);
        if (projected.invalidCount > 0) {
            throw new CommandExecutionError('Douyin search parser found result cards without stable video url or description');
        }
        if (projected.rows.length === 0) {
            throw new EmptyResultError('douyin search', `No Douyin videos matched "${keyword}".`);
        }
        return projected.rows;
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Reload the bridge/extension and retry so the injected evaluator matches the CLI version.
  2. Ensure opencli and the adapter file are the same version (reinstall/upgrade fully).
  3. Diff WAIT_AND_EXTRACT_JS's return contract against this check and align them.
  4. Log JSON.stringify(result) to inspect the actual shape before fixing either side.

Example fix

// before
if (!Array.isArray(result.cards)) {
    throw new CommandExecutionError('Douyin search: evaluator returned malformed cards payload');
}
// after
const cards = result.cards ?? result.data?.cards;
if (!Array.isArray(cards)) {
    throw new CommandExecutionError(`Douyin search: malformed cards payload: ${JSON.stringify(result).slice(0, 300)}`);
}
Defensive patterns

Strategy: type-guard

Type guard

function hasCardsArray(result) {
  return result != null && typeof result === 'object' && Array.isArray(result.cards);
}

Try / catch

try {
  rows = await douyinSearch(keyword);
} catch (e) {
  if (/malformed cards payload/.test(e.message)) {
    console.error('Evaluator/CLI version drift — reload the bridge extension and retry');
  }
  throw e;
}

Prevention

When it happens

Trigger: WAIT_AND_EXTRACT_JS updated to return cards as an object/null while search.js still expects an array; an intermediate wrapper (unwrapEvaluateResult) reshaped the payload; a modified/older version of one side is loaded.

Common situations: Partial upgrade where the page-injected JS is cached in Chrome but the CLI is new (or vice versa); local edits to the evaluator script; mixed-version opencli installation.

Understand the failure class

Related errors


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