{"record":{"id":"e2524cb921aa2cf7","repo":"jackwener/OpenCLI","slug":"weixin-search-did-not-expose-article-result-cards","errorCode":null,"errorMessage":"weixin search did not expose article result cards","messagePattern":"weixin search did not expose article result cards","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/weixin/search.js","lineNumber":137,"sourceCode":"            throw new CommandExecutionError('weixin search failed while loading Sogou results', detail);\n        }\n\n        if (!payload || typeof payload !== 'object' || !Array.isArray(payload.rows)) {\n            throw new CommandExecutionError('weixin search returned an unreadable browser payload', 'Sogou Weixin may have changed its result page structure.');\n        }\n        if (payload.blocked) {\n            throw new CommandExecutionError('Sogou Weixin blocked this search request', 'Open weixin.sogou.com in Chrome and complete any verification before retrying.');\n        }\n        if (payload.invalidCount > 0) {\n            throw new CommandExecutionError('Sogou Weixin returned article cards without required title or URL', 'The result page structure may have changed; refusing to return a partial result set.');\n        }\n\n        const rows = payload.rows;\n        if (rows.length === 0 && payload.empty) {\n            throw new EmptyResultError('weixin search', 'Try a different keyword or a different page number.');\n        }\n        if (rows.length === 0) {\n            throw new CommandExecutionError('weixin search did not expose article result cards', 'Sogou Weixin may have changed its selectors or returned a transient shell page.');\n        }\n\n        return rows.slice(0, limit).map((row, index) => ({\n            rank: (pageNo - 1) * 10 + index + 1,\n            page: pageNo,\n            title: row.title,\n            url: row.url,\n            summary: row.summary,\n            publish_time: row.publish_time,\n        }));\n    },\n});\n\nexport const __test__ = {\n    MAX_LIMIT,\n    normalizePage,\n    normalizeLimit,\n    buildSearchUrl,","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/weixin/search.js#L119-L155","documentation":"Thrown when the payload had a rows array of length 0 but was NOT flagged empty — meaning the page looked non-empty (or the emptiness heuristic failed) yet no article result cards could be extracted. The library suspects changed selectors or a transient shell page rather than a genuine no-results state. It is stricter than 4505 because the page state is inconsistent with a clean empty result.","triggerScenarios":"Sogou changed its result-list CSS selectors so extraction matches nothing; the page returned a transient shell/skeleton that never hydrated; a challenge variant the `blocked` heuristic didn't classify; very slow load where cards weren't in DOM at evaluate time.","commonSituations":"CLI version lagging behind a Sogou frontend update; intermittent infrastructure issues at Sogou serving partial pages; automation browser rendering differences (no JS execution of late hydration).","solutions":["Retry once — transient shell pages resolve on a second load","Upgrade the CLI to get updated selectors","Manually open the search URL in Chrome to check whether article cards render","If manual inspection shows a new layout, report the selector break to maintainers"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { rows = await weixinSearch(q); }\ncatch (e) {\n  if (String(e.message).includes('did not expose article result cards')) return retryWithBackoff(2);\n  throw e;\n}","preventionTips":["Retry on this specific message — often a transient shell page","Upgrade the CLI when it starts happening consistently","Verify in Chrome whether selectors changed"],"tags":["scraping","selectors","page-structure","transient"],"backgroundTag":"unexpected-response-schema","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}