jackwener/OpenCLI · error · Error

limit must be a positive integer

Error message

limit must be a positive integer

What it means

Input validation in the followers CLI's embedded page script: the --limit argument must be a positive integer. Because the arg is interpolated directly into the evaluate script, a non-integer (float, string, 0, negative) reaches Number.isInteger(limit) and the script aborts before any network call. It guards the count= query parameter and the slice(0, limit).

Source

Thrown at clis/instagram/followers.js:19

import { cli } from '@jackwener/opencli/registry';
import { buildResolveInstagramUserIdJs } from './_shared/user-id.js';
cli({
    site: 'instagram',
    name: 'followers',
    access: 'read',
    description: 'List followers of an Instagram user',
    domain: 'www.instagram.com',
    args: [
        { name: 'username', required: true, positional: true, help: 'Instagram username' },
        { name: 'limit', type: 'int', default: 20, help: 'Number of followers' },
    ],
    columns: ['rank', 'username', 'name', 'verified', 'private'],
    pipeline: [
        { navigate: 'https://www.instagram.com' },
        { evaluate: `(async () => {
  const username = \${{ args.username | json }};
  const limit = \${{ args.limit }};
  if (!Number.isInteger(limit) || limit < 1) throw new Error('limit must be a positive integer');
  const headers = { 'X-IG-App-ID': '936619743392459' };
  const opts = { credentials: 'include', headers };

  ${buildResolveInstagramUserIdJs()}

  const r2 = await fetch(
    'https://www.instagram.com/api/v1/friendships/' + userId + '/followers/?count=' + limit,
    opts
  );
  if (!r2.ok) throw new Error('Failed to fetch followers: HTTP ' + r2.status);
  const d2 = await r2.json();
  if (!d2 || typeof d2 !== 'object' || !Array.isArray(d2.users)) {
    throw new Error('Instagram followers returned malformed users payload');
  }
  return d2.users.slice(0, limit).map((u, i) => {
    if (!u || typeof u !== 'object') {
      throw new Error('Instagram followers returned malformed user row');
    }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a positive integer, e.g. --limit 20.
  2. In wrapper scripts, coerce with Math.trunc/parseInt and check Number.isInteger(n) && n > 0 before invoking.
  3. Use the default (20) by omitting the flag if you don't need a custom count.
  4. Clamp upper bounds to what you need; Instagram caps page counts server-side anyway.

Example fix

// before
opencli instagram followers someuser --limit 0
// after
const limit = Number(rawLimit);
if (!Number.isInteger(limit) || limit < 1) throw new Error('limit must be a positive integer');
opencli instagram followers someuser --limit 20
Defensive patterns

Strategy: validation

Validate before calling

function parseLimit(raw) {
  const n = typeof raw === 'number' ? raw : Number.parseInt(raw, 10);
  if (!Number.isInteger(n) || n < 1) throw new Error('limit must be a positive integer');
  return n;
}
// run before invoking the CLI

Type guard

function isPositiveInt(v) { return Number.isInteger(v) && v >= 1; }

Try / catch

try {
  await cli.followers(username, limit);
} catch (e) {
  if (String(e.message).includes('limit must be')) {
    console.error(`Bad --limit value: ${JSON.stringify(limit)}; use a positive integer`);
    process.exitCode = 2;
  } else throw e;
}

Prevention

When it happens

Trigger: Running the followers command with limit=0, a negative number, a decimal like 2.5, or a value interpolated as a non-number (e.g. quoted string, NaN from a bad int parse).

Common situations: Passing --limit 0 expecting 'unlimited'; passing a float; passing a huge number that overflows or a string in a wrapper script; forgetting the flag and some wrapper supplies an empty value.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/7485f2fce849d2ba. Report an issue: GitHub.