pydantic/monty · error · napi::Error
{name} must be a finite number
Error message
{name} must be a finite number What it means
napi-rs `Error` (Status::InvalidArg) thrown by `js_number_to_u64` in monty-js when a numeric option (e.g. a resource-limit field) is not a finite JavaScript number (NaN, Infinity, -Infinity). The helper validates f64 inputs coming over the napi boundary before they are narrowed to u64. This is the first guard in an ordered chain of checks.
Source
Thrown at crates/monty-js/src/limits.rs:104
Status::InvalidArg,
format!("{name} must fit in Rust usize on this platform"),
)
})
}
/// Converts a JavaScript `number` used for a size/count limit into `u64`.
///
/// JavaScript numbers are IEEE-754 doubles, so integers above `2^53 - 1`
/// cannot be represented exactly. Rejecting values outside the safe integer
/// range avoids silently rounding resource limits at the napi boundary.
///
/// Returns `Err` for non-finite, negative, fractional, or out-of-range inputs.
/// This helper does not panic.
pub(crate) fn js_number_to_u64(value: f64, name: &str) -> Result<u64> {
const JS_MAX_SAFE_INTEGER: u64 = (1_u64 << 53) - 1;
match value {
v if !v.is_finite() => Err(Error::new(
Status::InvalidArg,
format!("{name} must be a finite number"),
)),
v if v < 0.0 => Err(Error::new(Status::InvalidArg, format!("{name} must be non-negative"))),
v if v.fract() != 0.0 => Err(Error::new(Status::InvalidArg, format!("{name} must be an integer"))),
v if v > JS_MAX_SAFE_INTEGER as f64 => Err(Error::new(
Status::InvalidArg,
format!("{name} must be a safe integer (<= {JS_MAX_SAFE_INTEGER})"),
)),
v => {
#[expect(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
let value = v as u64;
Ok(value)
}
}
}
View on GitHub (pinned to adc986b362)
Solutions
- Replace NaN/Infinity with a finite number before passing the option
- Check `Number.isFinite(value)` on every numeric option before creating a pool/session
- If 'unlimited' is intended, omit the field and use the library default instead of Infinity
- Sanitize values parsed from JSON/env — `JSON.parse` cannot carry Infinity, so coercion code likely introduced it
Example fix
// before
await Monty.create({ maxMemory: 1024 * 1024 * 1024 * 1024 * 1024 }) // Infinity
// after
const maxMemory = Number.isFinite(opts.maxMemory) ? opts.maxMemory : 100 * 1024 * 1024;
await Monty.create({ maxMemory }) Defensive patterns
Strategy: validation
Validate before calling
function assertFiniteU64Option(name, v) {
if (!Number.isFinite(v)) throw new TypeError(`${name} must be a finite number`);
return v;
} Type guard
const isFiniteNumber = (v) => typeof v === 'number' && Number.isFinite(v);
Try / catch
try {
await Monty.create({ maxMemory: rawMaxMemory });
} catch (e) {
if (e instanceof napi.Status && /must be a finite number/.test(e.message)) {
// fall back to library default
} else throw e;
} Prevention
- Validate all numeric options with Number.isFinite before calls
- Never use Infinity as an 'unlimited' sentinel — omit the field instead
- Sanitize values coerced from env vars or JSON config
When it happens
Trigger: Calling any monty-js API that sets a numeric limit with `NaN`, `Infinity`, or `-Infinity`, e.g. `Monty.create({ maxMemory: Infinity })` or `pool.checkout({ requestTimeout: NaN })`, when that value flows into `js_number_to_usize` -> `js_number_to_u64`.
Common situations: Computing a limit from an arithmetic expression that overflows or divides by zero; loading limits from config where a JSON parser or env-var coercion produced NaN/Infinity; spreading `Infinity` as an 'unlimited' sentinel.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- {name} must be non-negative
- {name} must be an integer
- {name} must be a safe integer (<= 9007199254740991)
- Cannot convert JS Symbol to Monty value
- MontyFileHandle position exceeds JavaScript's maximum safe i
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/1e6295c3aa3ab075.
Report an issue: GitHub.