agalwood/Motrix · error · RangeError

${label} must be a non-negative bigint

Error message

${label} must be a non-negative bigint

What it means

RangeError from assertNonNegativeBigInt when value is not a bigint or is < 0n. Used for byte counters (downloaded/uploaded sizes) that overflow Number's safe-integer range and must be represented as BigInt.

Source

Thrown at src/core/inspector-activity/validators.ts:72

  if (!Number.isSafeInteger(value) || value <= 0) {
    throw new RangeError(`${label} must be a positive safe integer`)
  }
  return value
}

export function assertNonNegativeSafeInteger(
  value: number,
  label: string
): number {
  if (!Number.isSafeInteger(value) || value < 0) {
    throw new RangeError(`${label} must be a non-negative safe integer`)
  }
  return value
}

export function assertNonNegativeBigInt(value: bigint, label: string): bigint {
  if (typeof value !== 'bigint' || value < 0n) {
    throw new RangeError(`${label} must be a non-negative bigint`)
  }
  return value
}

export function normalizeSpeed(value: number, label: string): number {
  if (!Number.isFinite(value) || value < 0) {
    throw new RangeError(`${label} must be finite and non-negative`)
  }
  const normalized = Math.round(value)
  if (!Number.isSafeInteger(normalized)) {
    throw new RangeError(`${label} exceeds the JavaScript safe integer range`)
  }
  return normalized
}

export function saturatingAddSignedInt64(
  current: bigint,
  delta: bigint

View on GitHub (pinned to 1a708ee577)

Solutions

  1. Convert numbers to BigInt before calling: BigInt(value).
  2. Clamp with value < 0n ? 0n : value.
  3. Use a BigInt-aware JSON parser for round-tripping large counters.
  4. Default the field to 0n rather than undefined.

Example fix

// before
assertNonNegativeBigInt(payload.bytesDownloaded, 'bytesDownloaded') // it's a number -> RangeError

// after
const bytes = typeof payload.bytesDownloaded === 'bigint' ? payload.bytesDownloaded : BigInt(payload.bytesDownloaded)
assertNonNegativeBigInt(bytes < 0n ? 0n : bytes, 'bytesDownloaded')
Defensive patterns

Strategy: validation

Validate before calling

// Convert numbers to BigInt and clamp before validating.
const v = typeof raw === 'bigint' ? raw : BigInt(raw)
assertNonNegativeBigInt(v < 0n ? 0n : v, 'bytesDownloaded')

Type guard

function isNonNegativeBigInt(v: unknown): v is bigint {
  return typeof v === 'bigint' && v >= 0n
}

Try / catch

try {
  assertNonNegativeBigInt(value, 'bytesDownloaded')
} catch (err) {
  if (err instanceof RangeError && /non-negative bigint/.test(err.message)) {
    // default to 0n
  } else throw err
}

Prevention

When it happens

Trigger: assertNonNegativeBigInt(value, label) with typeof value !== 'bigint' || value < 0n. E.g. a plain number passed where bigint is required, a negative bigint, or undefined.

Common situations: Caller passed a Number instead of BigInt for a large byte count; a subtraction underflowed to a negative bigint; JSON deserialization produced a Number (JSON has no BigInt) that was not converted; missing field defaulted to undefined.

Related errors


AI-assisted analysis of agalwood/Motrix@1a708ee577 (2026-08-12). Data as JSON: /api/errors/ffd9e51fa7805ae5. Report an issue: GitHub.