agalwood/Motrix · error · RangeError

${label} exceeds the JavaScript safe integer range

Error message

${label} exceeds the JavaScript safe integer range

What it means

`normalizeSpeed` rounds the input with `Math.round` and then asserts the result is a JavaScript safe integer (within `Number.MAX_SAFE_INTEGER`, ~9.007e15). It throws this `RangeError` only when the input was finite and non-negative but rounded above the safe-integer bound. Speeds that large cannot be stored as a normal integer, so the validator refuses rather than silently truncating. The `label` in the message names which field overflowed (e.g. `peakDownloadBps`, `samples[3].down`).

Source

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

    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
): { value: bigint; saturated: boolean } {
  assertNonNegativeBigInt(current, 'current')
  assertNonNegativeBigInt(delta, 'delta')
  if (current > MAX_SIGNED_SQLITE_INTEGER) {
    throw new RangeError('current exceeds the signed int64 range')
  }
  if (delta > MAX_SIGNED_SQLITE_INTEGER - current) {
    return { value: MAX_SIGNED_SQLITE_INTEGER, saturated: true }
  }
  return { value: current + delta, saturated: false }
}

View on GitHub (pinned to 1a708ee577)

Solutions

  1. Clamp the speed before passing it in: `Math.min(Math.round(value), Number.MAX_SAFE_INTEGER)`.
  2. Verify the upstream unit — the field is bytes/second, not bits/second or bytes/interval.
  3. Audit the producer that fills `SpeedPoint.down/up` for an overflowed accumulator.
  4. If genuinely large speeds are expected, store the field as a bigint and redesign the validator instead of clamping.

Example fix

// before
checkpoint.peakDownloadBps = aggregateBps  // aggregateBps > 2^53
// after
checkpoint.peakDownloadBps = Math.min(aggregateBps, Number.MAX_SAFE_INTEGER)
Defensive patterns

Strategy: validation

Validate before calling

function safeSpeed(value: number, label: string): number {
  if (!Number.isFinite(value) || value < 0)
    throw new RangeError(`${label} must be finite and non-negative`)
  return Math.min(Math.round(value), Number.MAX_SAFE_INTEGER)
}

Try / catch

try {
  normalizeSpeed(value, label)
} catch (err) {
  if (err instanceof RangeError && err.message.endsWith('exceeds the JavaScript safe integer range')) {
    value = Number.MAX_SAFE_INTEGER
  } else throw err
}

Prevention

When it happens

Trigger: Calling `normalizeTransferSamples(samples)` or `validateCheckpoint(checkpoint)` with a sample whose `down`/`up`, or a checkpoint's `peakDownloadBps`/`peakUploadBps`, rounds to a value above 2^53-1. Concretely: a `SpeedPoint` carrying a downstream-aggregated bytes-per-second number that overflowed a 32-bit accumulator, or a bits-vs-bytes unit mismatch multiplying a legal speed by 8.

Common situations: Aggregator code that sums speeds across many peers without capping the result; tests hand-crafting unrealistic speeds; misreading an already-large byte count as bps; foreign telemetry with different units.

Related errors


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