{"record":{"id":"61b6e76602aa8338","repo":"jackwener/OpenCLI","slug":"jike-search-api-returned-a-malformed-pagination-cu","errorCode":null,"errorMessage":"Jike search API returned a malformed pagination cursor","messagePattern":"Jike search API returned a malformed pagination cursor","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/jike/search.js","lineNumber":60,"sourceCode":"    const seenCursors = new Set();\n    let loadMoreKey = null;\n    for (let pageIndex = 0; pageIndex < MAX_PAGES; pageIndex++) {\n        const body = await fetchSearchPage(page, keyword, loadMoreKey);\n        for (const item of body.data) {\n            if (item?.type !== 'ORIGINAL_POST') continue;\n            const row = mapPost(item);\n            if (seenIds.has(row.id)) continue;\n            seenIds.add(row.id);\n            rows.push(row);\n            if (rows.length >= limit) return rows;\n        }\n        const next = body.loadMoreKey;\n        if (next == null) {\n            if (rows.length === 0) throw new EmptyResultError('jike search', `No posts found for \"${keyword}\"`);\n            return rows;\n        }\n        if (typeof next !== 'object' || Array.isArray(next)) {\n            throw new CommandExecutionError('Jike search API returned a malformed pagination cursor');\n        }\n        const cursorKey = JSON.stringify(next);\n        if (seenCursors.has(cursorKey)) {\n            throw new CommandExecutionError('Jike search pagination returned a repeated cursor');\n        }\n        seenCursors.add(cursorKey);\n        loadMoreKey = next;\n    }\n    throw new CommandExecutionError(`Jike search pagination exceeded ${MAX_PAGES} pages before satisfying --limit`);\n}\n\ncli({\n    site: 'jike',\n    name: 'search',\n    access: 'read',\n    description: '搜索即刻帖子',\n    domain: 'web.okjike.com',\n    strategy: Strategy.COOKIE,","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/jike/search.js#L42-L78","documentation":"After exhausting a page, searchPosts reads body.loadMoreKey as the pagination cursor. The Jike API contract expects an object; if it is a non-object (string, number) or an array, the CLI throws CommandExecutionError rather than sending a cursor it cannot serialize correctly. This protects against silently broken pagination.","triggerScenarios":"The search response carries a loadMoreKey that is a string, number, boolean, or an Array instead of a plain object — e.g. Jike's API changed cursor format or returns an error marker in that field.","commonSituations":"Jike backend schema drift/rollback; requesting pagination with a logged-out or limited account whose responses differ; intermediate proxies rewriting response fields.","solutions":["Update the CLI/package to a version compatible with the current Jike API cursor format.","Retry later — if Jike changed formats this is server-side, not client-fixable.","Log the raw body.loadMoreKey value and inspect the actual type to confirm the schema change before patching locally."],"exampleFix":"// before\nif (typeof next !== 'object' || Array.isArray(next)) {\n  throw new CommandExecutionError('Jike search API returned a malformed pagination cursor');\n}\n// after: accept string cursors too\nconst validCursor = next != null && (typeof next === 'object' || typeof next === 'string');\nif (!validCursor) {\n  throw new CommandExecutionError('Jike search API returned a malformed pagination cursor');\n}","handlingStrategy":"try-catch","validationCode":"// preflight: confirm the search endpoint responds normally on page 1 before deep paging\nconst first = await runCli(['jike', 'search', keyword, '--limit', '5']);","typeGuard":"const isCursor = (v) => v != null && typeof v === 'object' && !Array.isArray(v);","tryCatchPattern":"try {\n  return await runCli(['jike', 'search', keyword, '--limit', n]);\n} catch (e) {\n  if (/malformed pagination cursor/.test(e.message)) return partialRows; // degrade gracefully\n  throw e;\n}","preventionTips":["Avoid very deep pagination (high --limit) where cursor bugs surface.","Update the CLI when Jike changes its loadMoreKey format.","Log body.loadMoreKey on failure to confirm the schema drift."],"tags":["api","pagination","jike"],"backgroundTag":"malformed-api-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}