{"record":{"id":"db72f171efdce1a1","repo":"jackwener/OpenCLI","slug":"limit-must-be-a-positive-integer-200","errorCode":null,"errorMessage":"'limit', 'must be a positive integer ≤ 200'","messagePattern":"'limit', 'must be a positive integer ≤ 200'","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/gemini/history.js","lineNumber":45,"sourceCode":"\nexport const historyCommand = cli({\n    site: 'gemini',\n    name: 'history',\n    access: 'read',\n    description: 'List visible Gemini web conversation history from the sidebar',\n    domain: GEMINI_DOMAIN,\n    strategy: Strategy.COOKIE,\n    browser: true,\n    siteSession: 'persistent',\n    navigateBefore: false,\n    args: [\n        { name: 'limit', type: 'int', default: 20, help: 'Max conversations to show' },\n    ],\n    columns: ['Index', 'Id', 'Title', 'Url'],\n    func: async (page, kwargs) => {\n        const rawLimit = Number(kwargs?.limit ?? 20);\n        if (!Number.isInteger(rawLimit) || rawLimit < 1 || rawLimit > 200) {\n            throw new ArgumentError('limit', 'must be a positive integer ≤ 200');\n        }\n        await ensureGeminiPage(page);\n        const conversations = await getGeminiConversationList(page);\n        if (!conversations.length) {\n            throw new EmptyResultError(\n                'gemini history',\n                'No Gemini conversation links were visible in the sidebar. Open the sidebar and confirm at least one chat is listed under Recents.',\n            );\n        }\n        // The sidebar mixes a \"New chat\" affordance (URL = /app, no id) into\n        // the same link list; drop entries that don't resolve to a real\n        // conversation id so callers get a clean conversation list.\n        const rows = conversations\n            .map((row) => ({ id: extractGeminiId(row.Url), title: row.Title || '', url: row.Url || '' }))\n            .filter((row) => row.id);\n        return rows.slice(0, rawLimit).map((row, idx) => ({\n            Index: idx + 1,\n            Id: row.id,","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/gemini/history.js#L27-L63","documentation":"The gemini history command validates its --limit option and throws ArgumentError('limit', 'must be a positive integer ≤ 200') when the value is not an integer in [1, 200]. The bound prevents requesting unbounded sidebar scraping, since only a limited Recents list exists. Note that default 20 is passed through Number(), so numeric strings like '25' are accepted but non-numeric strings are not.","triggerScenarios":"Calling `opencli gemini history` with --limit 0, negative, > 200, fractional (10.5), or a non-numeric string like 'all' or 'twenty'.","commonSituations":"Passing --limit all to try to see everything; a wrapper computing a limit from a ratio producing a float; typo like --limit 2000; shell variable expanding to empty so NaN results from Number(undefined ?? 20) misuse when kwarg is explicitly empty string.","solutions":["Use an integer between 1 and 200, e.g. --limit 50","Replace 'all' or other words with a concrete number (max useful is 200)","Round computed values with Math.round/Math.floor before passing","If you need more conversations than the limit, note the sidebar itself only exposes a bounded Recents list"],"exampleFix":"// before\nopencli gemini history --limit all\n// after\nopencli gemini history --limit 200","handlingStrategy":"validation","validationCode":"const limit = Math.round(Number(rawLimit ?? 20));\nif (!(limit >= 1 && limit <= 200)) throw new Error('limit must be an integer in [1, 200]');","typeGuard":"const isValidLimit = (v) => Number.isInteger(v) && v >= 1 && v <= 200;","tryCatchPattern":"try {\n  return await run(['gemini','history','--limit', String(limit)]);\n} catch (e) {\n  if (String(e.message).includes('positive integer ≤ 200')) {\n    return await run(['gemini','history','--limit','20']); // safe default\n  }\n  throw e;\n}","preventionTips":["Clamp limits: Math.min(200, Math.max(1, Math.round(x)))","Never pass words like 'all'; the hard cap is 200","Watch for empty-string limits, which coerce to 0/NaN"],"tags":["validation","argument-error","cli","limit"],"backgroundTag":"invalid-cli-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}