{"record":{"id":"13a30a24144889d6","repo":"jackwener/OpenCLI","slug":"xiaohongshu-search-cannot-identify-the-collapsed-b","errorCode":null,"errorMessage":"Xiaohongshu search cannot identify the collapsed browser target for safe replacement.","messagePattern":"Xiaohongshu search cannot identify the collapsed browser target for safe replacement\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/search.js","lineNumber":820,"sourceCode":"    const harvest = requireHarvestPayload(await page.evaluate(buildScrollHarvestJs('www.xiaohongshu.com', limit, harvestOptions)), 'www.xiaohongshu.com');\n    if (harvest.diag.securityBlock) {\n        throw new CliError('SECURITY_BLOCK', 'Xiaohongshu search was blocked by request-frequency or security controls.', 'Wait before retrying or use a different logged-in browser session.');\n    }\n    return harvest;\n}\n\nasync function replaceCollapsedTab(page, url) {\n    if (typeof page.getActivePage !== 'function' || typeof page.newTab !== 'function' ||\n        typeof page.setActivePage !== 'function' || typeof page.selectTab !== 'function' ||\n        typeof page.closeTab !== 'function') {\n        throw new CommandExecutionError(\n            'Xiaohongshu search rendered in a collapsed tab, but this browser session cannot replace the failed target.',\n            'Retry the command in a Browser Bridge session that supports tab replacement.',\n        );\n    }\n    const previousPage = page.getActivePage();\n    if (!previousPage) {\n        throw new CommandExecutionError('Xiaohongshu search cannot identify the collapsed browser target for safe replacement.');\n    }\n    let freshPage;\n    try {\n        freshPage = await page.newTab(url);\n        if (!freshPage) {\n            throw new Error('newTab returned no page identity');\n        }\n        page.setActivePage(freshPage);\n        await page.closeTab(previousPage);\n    }\n    catch (error) {\n        const cleanupErrors = [];\n        if (freshPage) {\n            let restoredPrevious = false;\n            try {\n                await page.selectTab(previousPage);\n                restoredPrevious = true;\n            }","sourceCodeStart":802,"sourceCodeEnd":838,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/search.js#L802-L838","documentation":"After confirming the session supports tab replacement, replaceCollapsedTab calls page.getActivePage() to snapshot which tab is collapsed so it can be safely closed after the new one is opened. If getActivePage() returns a falsy value, the function cannot know which target to replace and throws this CommandExecutionError rather than risking closing the wrong tab.","triggerScenarios":"In replaceCollapsedTab (clis/xiaohongshu/search.js:818-821): the session exposes all tab APIs, but page.getActivePage() returns null/undefined because the session has no currently-active page registered — e.g. the collapsed page was already detached, closed, or the session lost its active-page pointer mid-run.","commonSituations":"The target tab was closed externally (user or another automation step) between navigation and recovery; a session state bug where setActivePage was never called after goto; racing another script that manipulates tabs in the same browser-bridge session concurrently.","solutions":["Re-run the command in a fresh session — a lost active-page pointer usually only affects the current run.","Ensure no other automation is concurrently opening/closing tabs in the same browser session.","Check that the session wrapper registers an active page on goto; if using a custom session, call setActivePage after creating/navigating the page.","Upgrade the browser-bridge version if the active-page tracking is known to be buggy."],"exampleFix":"// before: custom session that never registers the active page\nconst page = await session.newTab(url);\nawait page.goto(url);\nawait run('xiaohongshu search', 'coffee');\n// after: register the active page so recovery can identify the collapsed target\nconst page = await session.newTab(url);\nawait session.setActivePage(page);\nawait page.goto(url);\nawait run('xiaohongshu search', 'coffee');","handlingStrategy":"try-catch","validationCode":"// Confirm the session has a registered active page before search\nif (typeof session.getActivePage !== 'function' || !session.getActivePage()) {\n  throw new Error('Session has no active page; call setActivePage after opening the tab');\n}","typeGuard":"function hasActivePage(session) { return Boolean(session?.getActivePage?.()); }","tryCatchPattern":"try {\n  rows = await cli('xiaohongshu search', query);\n} catch (err) {\n  if (err instanceof CommandExecutionError && /cannot identify the collapsed browser target/.test(err.message)) {\n    // restart with a clean session so active-page state is rebuilt\n    await session.close();\n    session = await openBridgeSession({ tabManagement: true });\n    rows = await cli('xiaohongshu search', query);\n  } else { throw err; }\n}","preventionTips":["Never close or detach the search tab from other automation while the command is running.","Ensure setActivePage is called after opening tabs in custom session wrappers.","Restart with a fresh session after this error — active-page state is not recoverable mid-run.","Avoid concurrent scripts sharing one browser-bridge session."],"tags":["browser-session","session-state","tab-management","xiaohongshu"],"backgroundTag":"lost-active-page-reference","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}