jackwener/OpenCLI · error · TimeoutError

xiaohongshu search filter ${detail}

Error message

xiaohongshu search filter ${detail}

What it means

When the filter-application script reports status 'timeout', requireFilterApplication throws this TimeoutError with the script's detail string and FILTER_SETTLE_SECONDS as the duration. The filter control was clicked but the UI never reached the expected settled state (e.g. chip never activated or results never refreshed) within the allowed wait.

Source

Thrown at clis/xiaohongshu/search.js:510

        return { status: 'ok' };
      })()
    `;
}

function requireFilterApplication(payload) {
    const result = unwrapEvaluateResult(payload);
    if (!result || typeof result !== 'object' || Array.isArray(result) || typeof result.status !== 'string') {
        throw new CommandExecutionError('Unexpected Xiaohongshu search filter result shape.');
    }
    if (result.status === 'ok') {
        return;
    }
    const detail = typeof result.detail === 'string' ? result.detail : 'unknown';
    if (result.status === 'auth') {
        throw new AuthRequiredError('www.xiaohongshu.com', 'Xiaohongshu search filters require a logged-in browser session');
    }
    if (result.status === 'timeout') {
        throw new TimeoutError(`xiaohongshu search filter ${detail}`, FILTER_SETTLE_SECONDS);
    }
    if (result.status === 'location') {
        throw new CommandExecutionError(`Xiaohongshu location filter was not applied (${detail}); enable browser geolocation permission.`);
    }
    if (result.status === 'capability') {
        throw new CommandExecutionError(`Xiaohongshu account-scoped filter was unavailable (${detail}); verify login and account access.`);
    }
    if (result.status === 'inactive') {
        throw new CommandExecutionError(`Xiaohongshu search filter chip did not become active (${detail}).`);
    }
    throw new CommandExecutionError(`Xiaohongshu search filter layout did not match the expected visible panel (${detail}).`);
}
/**
 * Build a "scroll until enough or plateaued" IIFE used in place of a fixed
 * `autoScroll({ times: N })`. Xiaohongshu's search results page lazy-loads
 * ~5-7 notes per scroll, so the previous `times: 2` capped extraction at
 * ~13 items regardless of `--limit` (see #1471). This helper drives scrolls
 * dynamically:

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry the search; transient slowness often resolves on a second attempt
  2. Increase headroom: run on a faster network/machine or with fewer concurrent browser tasks
  3. If it reproduces consistently, check whether Xiaohongshu changed the filter panel DOM and update the injected script's selectors/settle detection
  4. Catch TimeoutError specifically and re-run the harvest flow from page load

Example fix

// before
await applyFiltersAndHarvest(query, filters);
// after
try {
  await applyFiltersAndHarvest(query, filters);
} catch (e) {
  if (e instanceof TimeoutError) {
    await applyFiltersAndHarvest(query, filters); // one retry
    return;
  }
  throw e;
}
Defensive patterns

Strategy: retry

Try / catch

const applyWithRetry = async (attempt = 0) => {
  try {
    return await collectSearchHarvest(query, filters);
  } catch (e) {
    if (e instanceof TimeoutError && attempt < 2) {
      await new Promise(r => setTimeout(r, 1000 * (attempt + 1)));
      return applyWithRetry(attempt + 1);
    }
    throw e;
  }
};

Prevention

When it happens

Trigger: The page returns {status:'timeout', detail:'sort-panel'} when a filter chip/panel did not settle in time — slow network, heavy page, or the chip's active state selector no longer matching after a Xiaohongshu UI change.

Common situations: Slow/throttled network or cold browser profile making the SPA sluggish; Xiaohongshu redesigning filter markup so the settle detector waits forever; CPU-starved CI environments running headless browsers.

Related errors


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