jackwener/OpenCLI · error · CommandExecutionError

xiaohongshu ask returned a malformed page payload: missing m

Error message

xiaohongshu ask returned a malformed page payload: missing message identity

What it means

requireAskPayload throws this when the payload has an answer but lacks a parseable message_id or conversation_id. The library requires both IDs to identify the ask exchange (e.g. for follow-up questions); without them the result would be unusable, so it fails fast.

Source

Thrown at clis/xiaohongshu/ask.js:386

    if (error === 'send_message_failed') {
        throw new AuthRequiredError(XHS_WEB_HOST, 'Xiaohongshu 点点 did not accept the query. Check login status for www.xiaohongshu.com.');
    }
    throw new CommandExecutionError(
        `xiaohongshu ask failed: ${error || 'unknown error'}`,
        raw?.page_url ? `Page URL: ${raw.page_url}` : undefined,
    );
}

function requireAskPayload(raw) {
    if (!raw || typeof raw !== 'object') {
        throw new CommandExecutionError('xiaohongshu ask returned a malformed page payload');
    }
    const answer = cleanText(raw.answer || raw.base_info?.text || '');
    if (!answer) {
        throw new CommandExecutionError('xiaohongshu ask returned a malformed page payload: missing answer');
    }
    if (!compactSingleLine(raw.message_id) || !compactSingleLine(raw.conversation_id)) {
        throw new CommandExecutionError('xiaohongshu ask returned a malformed page payload: missing message identity');
    }
}

export const command = cli({
    site: 'xiaohongshu',
    name: 'ask',
    access: 'write',
    description: 'Ask 小红书点点 and return the answer with citation sources.',
    domain: XHS_WEB_HOST,
    strategy: Strategy.COOKIE,
    browser: true,
    navigateBefore: false,
    args: [
        { name: 'query', positional: true, required: true, help: 'Question for 点点' },
        { name: 'timeout', type: 'int', default: 90, help: 'Seconds to wait for the 点点 answer' },
        { name: 'source-limit', type: 'int', default: 10, help: 'Maximum citation sources to return' },
    ],
    columns: ASK_COLUMNS,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry — IDs may attach to the DOM slightly after the text appears; a longer --timeout helps.
  2. Update the library so the extraction script matches the current XHS DOM.
  3. Re-login if the conversation view behaves differently for the session.
  4. Log raw (minus sensitive text) to confirm which ID field is missing.
  5. Fall back to answer-only consumption if you don't need follow-ups.

Example fix

// before
const res = await xiaohongshuAsk({ query }); // requires message_id for follow-ups
// after
try {
  const res = await xiaohongshuAsk({ query });
} catch (e) {
  if (String(e.message).includes('missing message identity')) {
    return { answer: e.answer ?? null }; // degrade gracefully when IDs absent
  }
  throw e;
}
Defensive patterns

Strategy: fallback

Type guard

function hasMessageIdentity(p) {
  return typeof p.message_id === 'string' && p.message_id.length > 0 &&
         typeof p.conversation_id === 'string' && p.conversation_id.length > 0;
}

Try / catch

try {
  return await xiaohongshuAsk({ query });
} catch (e) {
  if (/missing message identity/.test(e.message) && !needFollowUps) {
    return { answer: null, degraded: true }; // proceed without follow-up support
  }
  throw e;
}

Prevention

When it happens

Trigger: raw.answer is non-empty but compactSingleLine(raw.message_id) or compactSingleLine(raw.conversation_id) is falsy — the script extracted text but not the message metadata from the XHS conversation.

Common situations: XHS changed the DOM attributes carrying message/conversation IDs; the reply rendered before IDs were attached to the DOM; a redesigned conversation view omits the elements the script reads.

Understand the failure class

Related errors


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