{"record":{"id":"957d0c50c4cbe7d6","repo":"jackwener/OpenCLI","slug":"twitter-following-limit-must-be-a-positive-integ","errorCode":null,"errorMessage":"twitter following --limit must be a positive integer","messagePattern":"twitter following --limit must be a positive integer","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/twitter/following.js","lineNumber":143,"sourceCode":"    description: 'Get accounts a Twitter/X user is following (defaults to the logged-in user when no user is given)',\n    domain: 'x.com',\n    strategy: Strategy.COOKIE,\n    browser: true,\n    args: [\n        {\n            name: 'user',\n            positional: true,\n            type: 'string',\n            required: false,\n            help: 'Twitter/X handle (with or without @). Omit to fetch the accounts the currently logged-in user follows.',\n        },\n        { name: 'limit', type: 'int', default: 50, help: 'Maximum number of following rows to return (default 50). Must be a positive integer.' },\n    ],\n    columns: ['screen_name', 'name', 'bio', 'followers'],\n    func: async (page, kwargs) => {\n        const limit = kwargs.limit === undefined || kwargs.limit === null ? 50 : Number(kwargs.limit);\n        if (!Number.isInteger(limit) || limit <= 0) {\n            throw new ArgumentError('twitter following --limit must be a positive integer', 'Example: opencli twitter following @elonmusk --limit 200');\n        }\n        const rawUser = String(kwargs.user ?? '').trim();\n        let targetUser = normalizeScreenName(rawUser);\n        if (rawUser && !targetUser) {\n            throw new ArgumentError('twitter following user must be a valid Twitter/X handle', 'Example: opencli twitter following @elonmusk --limit 200');\n        }\n\n        const cookies = await page.getCookies({ url: 'https://x.com' });\n        const ct0 = cookies.find((c) => c.name === 'ct0')?.value || null;\n        if (!ct0)\n            throw new AuthRequiredError('x.com', 'Not logged into x.com (no ct0 cookie)');\n\n        if (!targetUser) {\n            // Force a navigation to the home surface so the AppTabBar sidebar\n            // is rendered; the framework pre-nav lands on bare x.com which\n            // does not always expose AppTabBar_Profile_Link.\n            await page.goto('https://x.com/home');\n            await page.wait({ selector: '[data-testid=\"primaryColumn\"]' });","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/following.js#L125-L161","documentation":"ArgumentError thrown by the twitter following command when the --limit argument is not a positive integer. The command coerces the kwarg with Number() and requires Number.isInteger(limit) && limit > 0; anything else (0, negative, float, NaN, non-numeric string) fails validation before any browsing starts.","triggerScenarios":"Calling opencli twitter following with --limit 0, a negative number, a decimal like 50.5, a non-numeric string, or a value that coerces to NaN (e.g. --limit abc). kwargs.limit undefined/null defaults to 50 and does NOT trigger this.","commonSituations":"Shell quoting mistakes passing '50 100'; scripting with an unset variable that becomes an empty/invalid string; copy-pasting a float from config; using --limit 0 expecting 'unlimited'.","solutions":["Pass --limit as a positive whole number, e.g. --limit 200.","Fix the calling script so the limit variable is set to a valid integer before invocation.","Remove --limit entirely to use the default of 50.","If a wrapper produces floats, Math.trunc/round the value and check Number.isInteger before calling."],"exampleFix":"// before\nopencli twitter following @elonmusk --limit 0\n// after\nopencli twitter following @elonmusk --limit 200","handlingStrategy":"validation","validationCode":"function assertPositiveIntLimit(v, def = 50) {\n  if (v === undefined || v === null) return def;\n  const n = Number(v);\n  if (!Number.isInteger(n) || n <= 0) {\n    throw new Error(`--limit must be a positive integer, got: ${JSON.stringify(v)}`);\n  }\n  return n;\n}\nconst limit = assertPositiveIntLimit(rawLimit);","typeGuard":"const isPositiveInt = (v) => Number.isInteger(v) && v > 0;","tryCatchPattern":"import { ArgumentError } from '@jackwener/opencli/errors';\ntry {\n  rows = await opencli.twitter.following(user, { limit });\n} catch (e) {\n  if (e instanceof ArgumentError && /--limit must be a positive integer/.test(e.message)) {\n    rows = await opencli.twitter.following(user, { limit: 50 }); // fall back to default\n  } else throw e;\n}","preventionTips":["Always pass --limit as a plain positive integer","Guard scripted invocations with Number.isInteger checks before calling","Remember undefined/null safely defaults to 50; 0 and negatives do not","Avoid float or string-typed limit values from config files"],"tags":["argument-validation","cli","input-validation"],"backgroundTag":"invalid-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}