jackwener/OpenCLI · error · ArgumentError

nuget ${label} must be a positive integer

Error message

nuget ${label} must be a positive integer

What it means

This ArgumentError is thrown by requireBoundedInt in clis/nuget/utils.js when a caller passes a value for a bounded numeric option (label defaults to 'limit') that is not an integer or is <= 0. The library uses it to validate paging/limit parameters before they are sent to the NuGet API, failing fast on bad input rather than producing a confusing upstream request. Note that string values are coerced with Number(), so 'abc' or '' also land here.

Source

Thrown at clis/nuget/utils.js:28

export const NUGET_REGISTRATION_BASE = 'https://api.nuget.org/v3/registration5-semver1';
const UA = 'opencli-nuget-adapter/1.0 (+https://github.com/jackwener/opencli; mailto:opencli@example.com)';

// NuGet ID grammar (NuGet docs §package-id): up to 100 chars, alnum + `.` + `_` + `-`,
// must start with letter/digit. Case-insensitive; we lowercase for the registration URL
// because NuGet's CDN is case-sensitive on the path.
const PACKAGE_ID_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,99})$/;

export function requireString(value, label) {
    const s = String(value ?? '').trim();
    if (!s) throw new ArgumentError(`nuget ${label} cannot be empty`);
    return s;
}

export function requireBoundedInt(value, defaultValue, maxValue, label = 'limit') {
    const raw = value ?? defaultValue;
    const n = typeof raw === 'number' ? raw : Number(raw);
    if (!Number.isInteger(n) || n <= 0) {
        throw new ArgumentError(`nuget ${label} must be a positive integer`);
    }
    if (n > maxValue) {
        throw new ArgumentError(`nuget ${label} must be <= ${maxValue}`);
    }
    return n;
}

export function requirePackageId(value) {
    const raw = String(value ?? '').trim();
    if (!raw) throw new ArgumentError('nuget package id is required (e.g. "Newtonsoft.Json")');
    if (!PACKAGE_ID_PATTERN.test(raw)) {
        throw new ArgumentError(
            `nuget package id "${value}" is not a valid NuGet identifier`,
            'NuGet IDs are 1-100 chars: letters/digits/`.`/`_`/`-`, starting with letter or digit.',
        );
    }
    return raw;
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a positive integer for the option, e.g. limit: 20
  2. If the value comes from a string, ensure it is a clean integer string like '20' (trim; no thousand separators)
  3. Omit the option entirely to let the built-in defaultValue apply
  4. Sanitize with Number.isInteger(Number(value)) && Number(value) > 0 before calling

Example fix

// before
await nuget.limit(ctx, { limit: 0 });
// after
await nuget.limit(ctx, { limit: 20 }); // or omit limit to use the default
Defensive patterns

Strategy: validation

Validate before calling

function isPositiveInt(v) { const n = typeof v === 'number' ? v : Number(v); return Number.isInteger(n) && n > 0; }
if (!isPositiveInt(opts.limit)) throw new Error(`limit must be a positive integer, got ${JSON.stringify(opts.limit)}`);

Type guard

function isBoundedInt(v, max) { const n = typeof v === 'number' ? v : Number(v); return Number.isInteger(n) && n > 0 && n <= max; }

Try / catch

try {
  await nuget.limit(ctx, { limit });
} catch (e) {
  if (e instanceof ArgumentError && e.message.includes('must be a positive integer')) {
    limit = 20; // fall back to default
  } else throw e;
}

Prevention

When it happens

Trigger: Calling a nuget command or API wrapper with limit (or any labeled bounded option) set to 0, a negative number, a non-numeric string like 'ten' or '', a float like 2.5, or NaN.

Common situations: Users passing --limit 0 expecting 'unlimited'; shell scripts interpolating empty variables into CLI flags; parsing user input from forms without numeric validation; locale-formatted numbers ('1,000') failing Number() coercion.

Related errors


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