{"record":{"id":"595032fc75147ae9","repo":"jackwener/OpenCLI","slug":"twitter-likes-archive-incomplete","errorCode":"twitter_likes_archive_incomplete","errorMessage":"twitter_likes_archive_incomplete: stopped after ${pages} page(s); completion cannot be proven","messagePattern":"twitter_likes_archive_incomplete: stopped after (.+?) page\\(s\\); completion cannot be proven","errorType":"error_code","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/likes.js","lineNumber":372,"sourceCode":"        }\n        // Resume is only removed after the timeline is truly exhausted. Hitting\n        // --max-pages, partial API errors after some rows, or an interrupt must\n        // leave the resume file so the next run can continue.\n        if (exhausted)\n            removeResumeFile(resumeFile);\n        if (useOutputFile) {\n            return {\n                outputFile,\n                count: outputCount,\n                source: 'likes',\n                username,\n                complete: exhausted,\n                pages,\n                ...(exhausted ? {} : { cursor, resumeFile: resumeFile || null }),\n            };\n        }\n        if (fetchAll && !exhausted) {\n            throw new CommandExecutionError(\n                `twitter_likes_archive_incomplete: stopped after ${pages} page(s); completion cannot be proven`,\n                resumeFile ? `Resume with --resume-file ${resumeFile}` : 'Rerun with --resume-file to preserve continuation state.',\n            );\n        }\n        const trimmed = fetchAll ? allTweets : allTweets.slice(0, limit);\n        return applyTopByEngagement(trimmed, topByEngagement);\n    },\n});\nexport const __test__ = {\n    sanitizeQueryId,\n    buildLikesUrl,\n    parseLikes,\n    readResumeFile,\n};\n","sourceCodeStart":354,"sourceCodeEnd":387,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/likes.js#L354-L387","documentation":"A CommandExecutionError (code `twitter_likes_archive_incomplete`) thrown when --fetch-all was requested but the pagination loop stopped without proving the timeline was exhausted (exhausted === false). Since completion cannot be proven, the command refuses to return a partial archive; it preserves the resume file so a later run can continue.","triggerScenarios":"Running the likes command with fetchAll=true and the loop ends via --max-pages, a mid-run API error after some pages, or an interrupt, while a cursor still exists. The error message names how many pages were fetched and points at the resume file.","commonSituations":"Hitting the --max-pages cap during a large backfill; transient GraphQL failures partway through; killing the process with Ctrl-C during a long archive run.","solutions":["Rerun with the suggested --resume-file path printed in the remediation to continue from the saved cursor.","Increase --max-pages (or remove it) so the timeline can be fully drained.","Retry after a transient API failure — the resume file preserves progress, so no rows are lost.","If a partial archive is acceptable, drop --fetch-all so the command returns fetched rows with an explicit incomplete marker instead of throwing."],"exampleFix":"// before\nopencli twitter likes alice --fetch-all --max-pages 5\n// after: continue to completion\nopencli twitter likes alice --fetch-all --resume-file /tmp/twitter-likes-alice.resume.json","handlingStrategy":"retry","validationCode":"// ensure generous page budget before --fetch-all\nconst expectedMax = knownLikesCount ? Math.ceil(knownLikesCount / 20) + 5 : 100;\nif (maxPages < expectedMax) console.warn(`--max-pages ${maxPages} may not cover ~${expectedMax} pages; keep --resume-file`);","typeGuard":null,"tryCatchPattern":"try {\n  const archive = await cli.run(['twitter', 'likes', user, '--fetch-all']);\n} catch (e) {\n  if (String(e.message).startsWith('twitter_likes_archive_incomplete')) {\n    const resumeFile = /--resume-file (\\S+)/.exec(e.message)?.[1];\n    // rerun continuing from the saved cursor\n    return cli.run(['twitter', 'likes', user, '--fetch-all', '--resume-file', resumeFile]);\n  }\n  throw e;\n}","preventionTips":["Always pass an explicit --resume-file for fetch-all runs so progress survives interruptions.","Set --max-pages above your expected page count.","Schedule large archives with retry-on-incomplete logic.","Avoid Ctrl-C mid-run; if interrupted, resume rather than restart."],"tags":["twitter","pagination","incomplete-data","cli"],"backgroundTag":"incomplete-pagination-result","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}