{"record":{"id":"b82e30f1748bd59a","repo":"jackwener/OpenCLI","slug":"limit-must-be-a-positive-integer-b82e30","errorCode":null,"errorMessage":"limit must be a positive integer","messagePattern":"limit must be a positive integer","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/instagram/following.js","lineNumber":19,"sourceCode":"import { cli } from '@jackwener/opencli/registry';\nimport { buildResolveInstagramUserIdJs } from './_shared/user-id.js';\ncli({\n    site: 'instagram',\n    name: 'following',\n    access: 'read',\n    description: 'List accounts an Instagram user is following',\n    domain: 'www.instagram.com',\n    args: [\n        { name: 'username', required: true, positional: true, help: 'Instagram username' },\n        { name: 'limit', type: 'int', default: 20, help: 'Number of accounts' },\n    ],\n    columns: ['rank', 'username', 'name', 'verified', 'private'],\n    pipeline: [\n        { navigate: 'https://www.instagram.com' },\n        { evaluate: `(async () => {\n  const username = \\${{ args.username | json }};\n  const limit = \\${{ args.limit }};\n  if (!Number.isInteger(limit) || limit < 1) throw new Error('limit must be a positive integer');\n  const headers = { 'X-IG-App-ID': '936619743392459' };\n  const opts = { credentials: 'include', headers };\n\n  ${buildResolveInstagramUserIdJs()}\n\n  const PAGE_SIZE = 50;\n  const results = [];\n  const seen = new Set();\n  const seenCursors = new Set();\n  let maxId = undefined;\n  const baseUrl = 'https://www.instagram.com/api/v1/friendships/' + userId + '/following/';\n\n  while (results.length < limit) {\n    const params = new URLSearchParams({ count: String(PAGE_SIZE) });\n    if (maxId) params.set('max_id', maxId);\n    const r2 = await fetch(baseUrl + '?' + params.toString(), opts);\n    if (!r2.ok) throw new Error('Failed to fetch following: HTTP ' + r2.status);\n    const d2 = await r2.json();","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/instagram/following.js#L1-L37","documentation":"Identical input validation to the followers CLI but in the following command's embedded script: --limit must be a positive integer before any fetch occurs. The value is interpolated into the evaluate script and immediately checked with Number.isInteger(limit) && limit >= 1, guarding the paginated count parameter (PAGE_SIZE 50) and loop termination.","triggerScenarios":"Invoking the following command with limit=0, negative values, decimals, or a non-numeric interpolated value (string/NaN) from a wrapper or config file.","commonSituations":"Scripts passing string '20' or empty limit; users expecting 0 to mean 'all'; config files supplying floats or blank values; Shell quoting turning the number into a string.","solutions":["Pass a positive integer, e.g. --limit 50.","Sanitize in the calling script: parseInt then validate Number.isInteger(n) && n > 0.","Omit the flag to use the default if available.","Fix upstream config/wrapper so numeric values stay numeric through interpolation."],"exampleFix":"// before\nopencli instagram following someuser --limit -5\n// after\nconst limit = Math.trunc(Number(raw));\nif (!Number.isInteger(limit) || limit < 1) throw new Error('limit must be a positive integer');","handlingStrategy":"validation","validationCode":"function coercePositiveInt(raw) {\n  const n = typeof raw === 'number' ? raw : Number.parseInt(raw, 10);\n  if (!Number.isInteger(n) || n < 1) throw new Error('limit must be a positive integer');\n  return n;\n}\n// call before invoking the following command","typeGuard":"function isPositiveInt(v) { return Number.isInteger(v) && v >= 1; }","tryCatchPattern":"try {\n  await cli.following(username, limit);\n} catch (e) {\n  if (String(e.message).includes('limit must be')) {\n    console.error('Pass --limit as a positive integer, e.g. --limit 50');\n    process.exitCode = 2;\n  } else throw e;\n}","preventionTips":["Sanitize limit in wrappers/config so strings and floats never reach the CLI.","Use a sensible positive default instead of 0/'unlimited'.","Clamp limit to the maximum you actually paginate through (pages of 50).","Test argument interpolation paths to ensure numeric types survive."],"tags":["validation","argument-parsing","instagram"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}