jackwener/OpenCLI · error · ArgumentError

youtube history limit must be a positive integer

Error message

youtube history limit must be a positive integer

What it means

ArgumentError thrown by normalizeLimit when the `limit` argument to `youtube history` is not a positive integer. The library validates up front (Number.isInteger && > 0) before any page work, so invalid input fails fast. Acceptable values are integers from 1 to MAX_LIMIT (200).

Source

Thrown at clis/youtube/history.js:26

    CommandExecutionError,
    EmptyResultError,
    TimeoutError,
} from '@jackwener/opencli/errors';
import {
    prepareYoutubeApiPage,
    readYoutubeSapisid,
    SAPISID_HASH_FN,
} from './utils.js';

const DEFAULT_LIMIT = 30;
const MAX_LIMIT = 200;
const MAX_PAGES = 20;
const REQUEST_TIMEOUT_SECONDS = 15;

function normalizeLimit(value) {
    const limit = Number(value ?? DEFAULT_LIMIT);
    if (!Number.isInteger(limit) || limit <= 0) {
        throw new ArgumentError('youtube history limit must be a positive integer');
    }
    if (limit > MAX_LIMIT) {
        throw new ArgumentError(`youtube history limit must be <= ${MAX_LIMIT}`);
    }
    return limit;
}

cli({
    site: 'youtube',
    name: 'history',
    access: 'read',
    description: 'Get YouTube watch history',
    domain: 'www.youtube.com',
    strategy: Strategy.COOKIE,
    args: [
        { name: 'limit', type: 'int', default: DEFAULT_LIMIT, help: 'Max videos to return (default 30, max 200)' },
    ],
    columns: ['rank', 'title', 'channel', 'views', 'duration', 'url'],

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a positive integer for limit (1–200).
  2. Omit limit entirely to use the default (30).
  3. Coerce/validate before calling: Number.isInteger(Number(limit)) && Number(limit) > 0.
  4. If a float sneaks in from config, round it explicitly first.

Example fix

// before
await yt.history({ limit: 0 }); // ArgumentError
// after
await yt.history({ limit: 50 }); // or omit limit for default 30
Defensive patterns

Strategy: validation

Validate before calling

function validLimit(v) {
  const n = Number(v);
  return Number.isInteger(n) && n > 0 && n <= 200;
}
if (!validLimit(opts.limit)) throw new Error('limit must be an integer 1-200');

Type guard

function isPositiveInt(v) {
  return typeof v === 'number' && Number.isInteger(v) && v > 0;
}

Try / catch

try {
  return await yt.history({ limit });
} catch (e) {
  if (e instanceof ArgumentError) {
    return yt.history({}); // fall back to default limit
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing limit as 0, a negative number, a non-integer (e.g. 12.5), or a non-numeric string like 'abc' or '' — anything where Number(value) is not a positive integer. Note '' coerces to 0 and '30' coerces to 30.

Common situations: CLI users typing `--limit 0` or `--limit -5`; programmatic callers passing a string like 'twenty' or a float from config; passing null explicitly (null ?? DEFAULT means default applies, but 0 does not).

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/7d488c9f50eee09e. Report an issue: GitHub.