pydantic/monty · error · TypeError

invalid printFlushInterval: expected a non-negative number o

Error message

invalid printFlushInterval: expected a non-negative number of seconds, got ${interval}

What it means

`printFlushInterval` is given in seconds and is converted to a millisecond flush interval for the worker's print buffering. A non-finite (NaN/Infinity) or negative value cannot be turned into a valid timer interval, so the transport rejects it with a `TypeError` before creating the session. Zero is allowed and means line-buffered (unbuffered) flushing.

Source

Thrown at crates/monty-js/ts/worker/transport.ts:40

  Value as ComponentValue,
} from './component/monty.component.js'
import type { Dispatcher } from './host.js'
import { decodeValue, encodeValue } from './value.js'

type OnPrint = (stream: 'stdout' | 'stderr', text: string) => void

/**
 * Encodes a print flush interval (seconds) as whole milliseconds for the WIT
 * `u32`, mirroring `monty-pool`'s `flush_interval_ms`.
 *
 * The component encodes a `u32` as `val >>> 0`, which would silently wrap a
 * negative or non-finite value into a huge interval, so reject those here.
 * Zero is the line-buffering sentinel, so a positive interval never rounds
 * down into it.
 */
function flushIntervalMs(interval: number): number {
  if (!Number.isFinite(interval) || interval < 0) {
    throw new TypeError(`invalid printFlushInterval: expected a non-negative number of seconds, got ${interval}`)
  }
  return interval === 0 ? 0 : Math.min(Math.max(Math.floor(interval * 1000), 1), 0xffffffff)
}

/** Resource limits mirrored from the napi pool; the transport enforces `maxSuspensions`. */
export interface ResourceLimits {
  maxDurationSecs?: number
  maxMemory?: number
  gcInterval?: number
  maxRecursionDepth?: number
  maxSuspensions?: number
}

/** Session-creation options sent to the component worker. */
export interface WorkerSessionConfig {
  scriptName?: string
  limits?: ResourceLimits
  typeCheck?: boolean

View on GitHub (pinned to adc986b362)

Solutions

  1. Pass a finite, non-negative number of seconds (e.g. `0.05` for 50ms) or `0` for line-buffered behavior.
  2. Clamp/validate the value before constructing the config: `const interval = Number.isFinite(v) && v >= 0 ? v : 0.05`.
  3. If the value comes from user config, sanitize at load time so NaN/negatives become the documented default instead of reaching checkout().
  4. Omit `printFlushInterval` entirely to use the library default when you don't need custom flushing.

Example fix

// before
const session = await pool.checkout({ printFlushInterval: Number(process.env.FLUSH_S) }) // NaN if unset

// after
const raw = Number(process.env.FLUSH_S)
const printFlushInterval = Number.isFinite(raw) && raw >= 0 ? raw : 0.05
const session = await pool.checkout({ printFlushInterval })
Defensive patterns

Strategy: validation

Validate before calling

function sanitizeInterval(v: unknown): number {
  const n = Number(v)
  return Number.isFinite(n) && n >= 0 ? n : 0
}

Type guard

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

Try / catch

try {
  session = await pool.checkout({ printFlushInterval: raw })
} catch (err) {
  if (err instanceof TypeError && err.message.includes('printFlushInterval')) {
    session = await pool.checkout({ printFlushInterval: 0.05 })
  } else throw err
}

Prevention

When it happens

Trigger: Passing `printFlushInterval: NaN`, `Infinity`, `-1`, or any non-finite/negative number in the `WorkerSessionConfig` handed to `pool.checkout()` or `WorkerTransport.create()`.

Common situations: Computing the interval from a config parse that produced NaN (e.g. `Number(undefined)`), unit confusion (writing a negative 'disable' sentinel), or copying a config from another library that uses `Infinity` to mean 'never flush'.

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