pydantic/monty · error · TypeError

maxBytes must be a finite non-negative number or null

Error message

maxBytes must be a finite non-negative number or null

What it means

The print collector's constructor `maxBytes` must be `null` (cap disabled) or a finite non-negative number. `NaN`/`Infinity` would make the `used > maxBytes` comparison never trip (silently disabling the cap) and negatives are meaningless, so a `TypeError` is thrown at construction time.

Source

Thrown at crates/monty-js/ts/print.ts:48

 * Package-internal — do not re-export from index/node/wasm.
 */
function checkPrintCollectLimit(current: number, add: number, maxBytes: number | null): void {
  if (maxBytes === null) return
  // Caps stay far below Number.MAX_SAFE_INTEGER; plain + is exact for our sizes.
  const used = current + add
  if (used > maxBytes) {
    throw new MontyRuntimeError('MemoryError', `memory limit exceeded: ${used} bytes > ${maxBytes} bytes`)
  }
}

/**
 * Normalize constructor `maxBytes`: only `null` disables the cap.
 * Rejects NaN/Infinity (which would make `used > maxBytes` never true) and negatives.
 */
function resolveMaxBytes(maxBytes: number | null): number | null {
  if (maxBytes === null) return null
  if (typeof maxBytes !== 'number' || !Number.isFinite(maxBytes) || maxBytes < 0) {
    throw new TypeError('maxBytes must be a finite non-negative number or null')
  }
  return maxBytes
}

/**
 * Accumulates print fragments into one string. Pass as `printCallback`.
 * Default cap: DEFAULT_MAX_PRINT_COLLECT_BYTES. Pass maxBytes: null to disable.
 * Host-side only — not covered by ResourceLimits.maxMemory.
 *
 * `maxBytes` must be a finite non-negative number or `null` (validated at construction).
 */
export class CollectString {
  private buf = ''
  private collectedBytes = 0
  private readonly maxBytes: number | null

  constructor(maxBytes: number | null = DEFAULT_MAX_PRINT_COLLECT_BYTES) {
    this.maxBytes = resolveMaxBytes(maxBytes)

View on GitHub (pinned to adc986b362)

Solutions

  1. Pass `null` to disable the cap — not `Infinity` or `-1`
  2. Validate numeric config before construction: `Number.isFinite(v) && v >= 0`
  3. Coerce config with `Number(v)` and check for NaN before use

Example fix

// before
const collector = new PrintCollector({ maxBytes: Infinity })
// after
const collector = new PrintCollector({ maxBytes: null }) // disable cap
Defensive patterns

Strategy: validation

Validate before calling

if (maxBytes !== null && (typeof maxBytes !== 'number' || !Number.isFinite(maxBytes) || maxBytes < 0)) {
  throw new Error(`invalid maxBytes: ${maxBytes}`)
}

Type guard

function isValidMaxBytes(v: unknown): v is number | null {
  return v === null || (typeof v === 'number' && Number.isFinite(v) && v >= 0)
}

Try / catch

try {
  const collector = new PrintCollector({ maxBytes })
} catch (e) {
  if (e instanceof TypeError && e.message.includes('maxBytes')) {
    const collector = new PrintCollector({ maxBytes: null })
  } else throw e
}

Prevention

When it happens

Trigger: `new PrintCollector({ maxBytes: Infinity })` intending 'unlimited', a NaN from a failed `parseFloat` of config, or a negative number.

Common situations: Using `Infinity` as an 'unlimited' sentinel; unvalidated env/JSON config parsed to NaN; a `-1` sentinel for 'no limit'.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13). Data as JSON: /api/errors/7d15aa42a1da3619. Report an issue: GitHub.