pydantic/monty · error · RangeError

assertMessageAnnotations must be a boolean or an integer bet

Error message

assertMessageAnnotations must be a boolean or an integer between 1 and 2**32 - 1

What it means

`assertMessageAnnotations` controls how many annotated asserts are kept and must be `true`, `false`, or a positive 32-bit integer. Values that are non-integers, `< 1`, or exceed `2**32 - 1` cannot be encoded as a uint32 on the wire, so a `RangeError` is thrown up front.

Source

Thrown at crates/monty-js/ts/options.ts:71

/**
 * The `assertMessageAnnotations` checkout option: `true`/`false`, or an
 * integer customizing the per-operand repr truncation length (in bytes,
 * default 120) of introspected `assert` failure messages.
 */
export type AssertMessageAnnotations = boolean | number

/**
 * Normalizes {@link AssertMessageAnnotations} to the wire encoding of
 * `Configure.assert_message_annotations`: `undefined`/`true` → absent (the
 * child's default, a 120-byte truncation), `false` → `0` (off), an integer →
 * a custom truncation length. Throws `RangeError` for numbers the wire's
 * uint32 cannot carry (non-integers, `< 1`, `> 2**32 - 1`).
 */
export function encodeAssertMessageAnnotations(value: AssertMessageAnnotations | undefined): number | undefined {
  if (value === undefined || value === true) return undefined
  if (value === false) return 0
  if (!Number.isInteger(value) || value < 1 || value > 0xffff_ffff) {
    throw new RangeError('assertMessageAnnotations must be a boolean or an integer between 1 and 2**32 - 1')
  }
  return value
}

View on GitHub (pinned to adc986b362)

Solutions

  1. Use `true` to keep all annotated asserts, `false`/`0` to disable, or an integer >= 1 and <= 4294967295
  2. Clamp and floor numeric config: `Math.min(Math.max(Math.floor(v), 1), 0xffff_ffff)`
  3. Replace sentinel 'unlimited' values with `true`

Example fix

// before
const session = await pool.checkout({ assertMessageAnnotations: -1 }) // unlimited?
// after
const session = await pool.checkout({ assertMessageAnnotations: true }) // or an integer like 1000
Defensive patterns

Strategy: validation

Validate before calling

const v = opts.assertMessageAnnotations
if (!(v === undefined || typeof v === 'boolean' || (Number.isInteger(v) && v >= 1 && v <= 0xffff_ffff))) {
  throw new Error(`invalid assertMessageAnnotations: ${v}`)
}

Type guard

function isValidAssertAnnotations(v: unknown): boolean {
  return v === undefined || typeof v === 'boolean' ||
    (typeof v === 'number' && Number.isInteger(v) && v >= 1 && v <= 0xffff_ffff)
}

Try / catch

try {
  session = await pool.checkout(opts)
} catch (e) {
  if (e instanceof RangeError && e.message.includes('assertMessageAnnotations')) {
    delete opts.assertMessageAnnotations // use default
    session = await pool.checkout(opts)
  } else throw e
}

Prevention

When it happens

Trigger: `pool.checkout({ assertMessageAnnotations: 0 })`, a float like `1.5`, a huge number like `2**40`, or a string `'true'` instead of a boolean.

Common situations: Config value parsed from JSON/env ending up as a string or float; intent to 'unlimited' encoded as 0 or a sentinel like `Infinity` or `-1`.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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