jackwener/OpenCLI · error · CommandExecutionError

Maimai search returned malformed API payload

Error message

Maimai search returned malformed API payload

What it means

CommandExecutionError thrown when the value returned from the in-page maimai API call is not a plain object (null, array, or primitive). The CLI treats any non-object payload as evidence that the API contract broke, so it refuses to continue parsing.

Source

Thrown at clis/maimai/search-talents.js:128

        body: JSON.stringify(body),
      });

      const result = await res.json();

      // Check login status
      if (res.status === 401 || res.status === 403 || result.error_code === 20002) {
        throw new Error('需要登录!请先在浏览器中访问 maimai.cn 并登录');
      }

      if (result.code !== 200 && result.code !== 0) {
        throw new Error(result.message || result.error || 'API 请求失败');
      }

      return result;
    }`);

    if (!data || typeof data !== 'object' || Array.isArray(data)) {
      throw new CommandExecutionError('Maimai search returned malformed API payload');
    }

    // Extract talent list from response. Missing list fields mean the API
    // shape drifted; only an explicit empty array is a true empty result.
    const talentListCandidates = [
      data.data?.list,
      data.data?.talent_list,
      data.list,
      data.talent_list,
    ];
    const talentList = talentListCandidates.find((value) => Array.isArray(value));
    if (!talentList) {
      throw new CommandExecutionError('Maimai search API payload missing talent list');
    }

    if (talentList.length === 0) {
      throw new EmptyResultError('maimai search-talents', `未找到匹配 "${query}" 的候选人`);
    }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log the raw payload before validation to see what actually came back.
  2. Check you are not being redirected to a login/captcha page (sign in to maimai.cn in the browser).
  3. Retry the command; transient proxy or CDN issues can corrupt the payload.
  4. Update the CLI if the endpoint's top-level shape changed.

Example fix

// before
if (!data || typeof data !== 'object' || Array.isArray(data)) {
  throw new CommandExecutionError('Maimai search returned malformed API payload');
}
// after
if (!data || typeof data !== 'object' || Array.isArray(data)) {
  console.error('payload:', typeof data, String(data).slice(0, 200));
  throw new CommandExecutionError('Maimai search returned malformed API payload — likely an HTML login/captcha page instead of JSON');
}
Defensive patterns

Strategy: type-guard

Type guard

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

Try / catch

try {
  const data = await fetchMaimaiSearch(query);
} catch (e) {
  if (/malformed API payload/.test(e.message)) {
    console.error('Non-JSON payload — sign in to maimai.cn and check for captcha pages');
  } else throw e;
}

Prevention

When it happens

Trigger: The evaluate/injected script returns undefined or a string (e.g. HTML error page, JSON parse produced non-object), or the fetch returned an array at top level.

Common situations: Maimai serving an HTML login/anti-bot page instead of JSON, network proxy mangling the response, page navigation interrupting the evaluate call.

Understand the failure class

Related errors


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