{"record":{"id":"8793b381bdbc23ba","repo":"jackwener/OpenCLI","slug":"xiaohongshu-search-filter-chip-did-not-become-acti","errorCode":null,"errorMessage":"Xiaohongshu search filter chip did not become active (${detail}).","messagePattern":"Xiaohongshu search filter chip did not become active \\((.+?)\\)\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/search.js","lineNumber":519,"sourceCode":"    }\n    if (result.status === 'ok') {\n        return;\n    }\n    const detail = typeof result.detail === 'string' ? result.detail : 'unknown';\n    if (result.status === 'auth') {\n        throw new AuthRequiredError('www.xiaohongshu.com', 'Xiaohongshu search filters require a logged-in browser session');\n    }\n    if (result.status === 'timeout') {\n        throw new TimeoutError(`xiaohongshu search filter ${detail}`, FILTER_SETTLE_SECONDS);\n    }\n    if (result.status === 'location') {\n        throw new CommandExecutionError(`Xiaohongshu location filter was not applied (${detail}); enable browser geolocation permission.`);\n    }\n    if (result.status === 'capability') {\n        throw new CommandExecutionError(`Xiaohongshu account-scoped filter was unavailable (${detail}); verify login and account access.`);\n    }\n    if (result.status === 'inactive') {\n        throw new CommandExecutionError(`Xiaohongshu search filter chip did not become active (${detail}).`);\n    }\n    throw new CommandExecutionError(`Xiaohongshu search filter layout did not match the expected visible panel (${detail}).`);\n}\n/**\n * Build a \"scroll until enough or plateaued\" IIFE used in place of a fixed\n * `autoScroll({ times: N })`. Xiaohongshu's search results page lazy-loads\n * ~5-7 notes per scroll, so the previous `times: 2` capped extraction at\n * ~13 items regardless of `--limit` (see #1471). This helper drives scrolls\n * dynamically:\n *\n *   - count visible `section.note-item` rows (excluding related-search\n *     `.query-note-item` rows)\n *   - if count >= targetCount → break (got enough)\n *   - if two consecutive scrolls add no new rows → break (DOM plateaued,\n *     no more lazy-load available)\n *   - hard cap at `maxScrolls` iterations (default 15) to bound runtime\n *\n * Exported so the rednote adapter (same DOM shape) can reuse it.","sourceCodeStart":501,"sourceCodeEnd":537,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/search.js#L501-L537","documentation":"This CommandExecutionError is thrown by requireFilterApplication when the in-page filter script reports status 'inactive': a requested Xiaohongshu search filter chip (a non-location, non-account option) was clicked but never became active within the 2.5s poll window, or the final settle check found it no longer active. The library throws it because a filter silently not applying would yield results that do not match the requested search scope. The detail field carries the group/option path (e.g. 'sort/popularity') that failed.","triggerScenarios":"Calling the xiaohongshu search command with filter requests (e.g. --filter sort/time) where clicking the chip in the filter panel does not toggle its active class within 2500ms, or the chip loses active state during the FILTER_SETTLE_SECONDS settle check after results reload.","commonSituations":"Xiaohongshu front-end DOM changes rename or restructure chip elements; a page re-render replaces the chip node mid-click; slow page/network makes the chip activate after the 2.5s poll expires; the requested option is disabled for that query (e.g. filters not offered for this keyword).","solutions":["Retry the search once — transient re-renders can delay the chip activation beyond the 2.5s window.","Log the detail field to identify which group/option failed, then drop or replace that filter in your request.","Update the CLI to the latest version, since DOM-shape changes on xiaohongshu.com are the most common root cause.","Run with a logged-in session; some filter options require authentication to activate.","Inspect the page manually in the automation browser to confirm the chip exists and is clickable."],"exampleFix":"// before\nawait cli.search({ query: 'coffee', filters: [{ group: 'sort', option: 'popular' }] });\n// after\ntry {\n  await cli.search({ query: 'coffee', filters: [{ group: 'sort', option: 'popular' }] });\n} catch (e) {\n  if (/filter chip did not become active/.test(e.message)) {\n    await cli.search({ query: 'coffee' }); // retry without the flaky filter\n  } else throw e;\n}","handlingStrategy":"try-catch","validationCode":"const filters = [{ group: 'sort', option: 'time' }];\nconst supportedGroups = ['sort', 'note_type', 'range'];\nif (filters.some(f => !supportedGroups.includes(f.group) || typeof f.option !== 'string')) {\n  throw new Error('unsupported xiaohongshu search filter');\n}","typeGuard":"function isFilterRequest(f) {\n  return typeof f === 'object' && f !== null\n    && typeof f.group === 'string' && typeof f.option === 'string';\n}","tryCatchPattern":"try {\n  await xhs.search({ query, filters });\n} catch (e) {\n  if (e instanceof CommandExecutionError && /chip did not become active/.test(e.message)) {\n    // retry once, then degrade to unfiltered search\n    try { await xhs.search({ query, filters }); }\n    catch { await xhs.search({ query }); }\n  } else throw e;\n}","preventionTips":["Keep the CLI updated since chip selectors depend on the live xiaohongshu.com DOM.","Log the detail field (group/option) to identify flaky filters quickly.","Run logged-in sessions — more filter options activate reliably.","Retry failed filter applications once before degrading to unfiltered search.","Avoid stacking many filters in one request; failures compound."],"tags":["filter","dom-automation","puppeteer"],"backgroundTag":"filter-chip-not-active","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}