jackwener/OpenCLI · error · ArgumentError

offset must be a non-negative integer

Error message

offset must be a non-negative integer

What it means

normalizeOffset validates the offset paging option. It throws when the value is not an integer or is negative — this message covers the negative/non-integer case (separate from the multiple-of-100 rule). HLTV stats endpoints page in fixed 100-row blocks, so arbitrary offsets are meaningless.

Source

Thrown at clis/hltv/utils.js:74

export const VERSIONS = {
  both: null,
  cs2: 'CS2',
  csgo: 'CSGO',
};

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

export function normalizeOffset(value, defaultValue = 0) {
  const raw = value ?? defaultValue;
  const n = Number(raw);
  if (!Number.isInteger(n) || n < 0) throw new ArgumentError('offset must be a non-negative integer');
  if (n % 100 !== 0) throw new ArgumentError('offset must be a multiple of 100');
  return n;
}

export function normalizeChoice(value, defaultValue, choices, label) {
  const raw = String(value ?? defaultValue);
  if (!Object.prototype.hasOwnProperty.call(choices, raw)) {
    throw new ArgumentError(`${label} must be one of: ${Object.keys(choices).join(', ')}`);
  }
  return raw;
}

export function parseNumber(value) {
  const raw = String(value ?? '').replace(/\s+/g, ' ').trim();
  if (!raw || raw === '-' || raw.toLowerCase() === 'n/a') return null;
  const match = raw.replace(/,/g, '').match(/-?\d+(?:\.\d+)?/);
  if (!match) return null;
  const n = Number(match[0]);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use a non-negative integer offset that is a multiple of 100 (0, 100, 200...)
  2. Remember offset is 0-based; page N corresponds to offset (N-1)*limit only if limit is 100
  3. Check the script logic that increments the offset between pages

Example fix

// before
--offset -100
// after
--offset 0  # offsets start at 0 and increase in steps of 100
Defensive patterns

Strategy: validation

Validate before calling

const n = Number(opts.offset);
if (!Number.isInteger(n) || n < 0) throw new Error('offset must be a non-negative integer');

Type guard

const isOffset = (v) => Number.isInteger(Number(v)) && Number(v) >= 0;

Try / catch

try {
  await hltv.results({ offset });
} catch (e) {
  if (e.name === 'ArgumentError' && e.message.includes('offset')) { offset = 0; /* retry with default */ }
  else throw e;
}

Prevention

When it happens

Trigger: Calling a command with --offset -100 or a non-integer like 50.5; passing offset as a non-numeric string that Number() coerces to NaN.

Common situations: Scripts computing offsets with buggy arithmetic producing negatives; users assuming 1-based paging and passing offset 1 expecting page 2.

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