jackwener/OpenCLI · error · CommandExecutionError

Unexpected Xiaohongshu search harvest row ${index + 1} URL;

Error message

Unexpected Xiaohongshu search harvest row ${index + 1} URL; expected a trusted note URL.

What it means

The row's url field must parse to a trusted note URL via noteUrlInfo(row.url, webHost) — i.e. a xiaohongshu note link on the expected host yielding a note key. Otherwise the row is rejected, preventing untrusted or off-site URLs from entering the output.

Source

Thrown at clis/xiaohongshu/search.js:301

        return parsed.protocol === 'https:' &&
            parsed.hostname.toLowerCase() === webHost.toLowerCase() &&
            /^\/user\/profile\/[^/]+\/?$/i.test(parsed.pathname);
    }
    catch {
        return false;
    }
}
function requireTrustedHarvestRow(row, index, webHost) {
    if (!row || typeof row !== 'object' || Array.isArray(row)) {
        throw new CommandExecutionError(`Unexpected Xiaohongshu search harvest row ${index + 1} shape; expected an object.`);
    }
    for (const field of ['title', 'author', 'likes', 'url', 'author_url']) {
        if (typeof row[field] !== 'string') {
            throw new CommandExecutionError(`Unexpected Xiaohongshu search harvest row ${index + 1} shape; expected string ${field}.`);
        }
    }
    if (!noteUrlInfo(row.url, webHost).key) {
        throw new CommandExecutionError(`Unexpected Xiaohongshu search harvest row ${index + 1} URL; expected a trusted note URL.`);
    }
    if (!isTrustedAuthorUrl(row.author_url, webHost)) {
        throw new CommandExecutionError(`Unexpected Xiaohongshu search harvest row ${index + 1} author URL; expected a trusted profile URL.`);
    }
    return row;
}
function requireHarvestPayload(payload, webHost) {
    const result = unwrapEvaluateResult(payload);
    const diag = result?.diag;
    if (!result || typeof result !== 'object' || Array.isArray(result) || !Array.isArray(result.rows) ||
        !diag || typeof diag !== 'object' || Array.isArray(diag) ||
        typeof diag.securityBlock !== 'boolean' || typeof diag.stopReason !== 'string' ||
        !Number.isFinite(diag.scrollHeight) || diag.scrollHeight < 0 ||
        !Number.isFinite(diag.clientHeight) || diag.clientHeight < 0 ||
        !Number.isSafeInteger(diag.cardCount) || diag.cardCount < 0 ||
        !(diag.feedClientHeight === null || (Number.isFinite(diag.feedClientHeight) && diag.feedClientHeight >= 0)) ||
        !Number.isSafeInteger(diag.distinctCardTops) || diag.distinctCardTops < 0) {
        throw new CommandExecutionError('Unexpected Xiaohongshu search harvest payload shape; expected rows plus typed diagnostics.');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run the search; ads and odd cards often cause one-off bad URLs.
  2. Update the CLI so noteUrlInfo recognizes the current xiaohongshu note URL format.
  3. Check whether a proxy/webHost override is misconfigured, making trusted hosts untrusted.
  4. Report persistent URL rejections with sample URLs so the trusted-host allowlist can be extended.
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeNoteUrl(u) {
  try {
    const url = new URL(u);
    return /xiaohongshu\.com$/.test(url.hostname) &&
      /(\/explore\/|\/discovery\/item\/)/.test(url.pathname);
  } catch { return false; }
}
// filter rows before trusting downstream output

Type guard

function isTrustedNoteUrl(u, webHost) {
  return typeof u === 'string' && new URL(u).hostname === webHost;
}

Try / catch

try {
  const rows = await searchNotes(query);
} catch (e) {
  if (String(e.message).includes('expected a trusted note URL')) {
    console.error('Off-format/off-host note link harvested; retry or update CLI:', e.message);
    return searchNotes(query);
  }
  throw e;
}

Prevention

When it happens

Trigger: A harvested row's url is empty, a relative link, a search/explore redirect, or a non-note xiaohongshu URL (or wrong host), so noteUrlInfo returns no key.

Common situations: Promoted/ad cards linking off-site or to campaign pages, xiaohongshu changing note URL format (e.g. new path segments or short-link redirects), or the harvest script capturing the card's click handler target instead of the canonical note href.

Related errors


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