pydantic/monty · critical
LongIntId overflow
Error message
LongIntId overflow
What it means
`InternTable::intern_long_int` converts the table's length to a `LongIntId` backed by a small unsigned integer; the `expect` panics if there are more interned big integers than the ID type can represent. This is an interpreter-internal invariant, not a catchable error: it only fires after ~4 billion distinct long-int literals are interned in one session.
Source
Thrown at crates/monty/src/intern.rs:1422
/// builtin names before the runtime table is built.
pub fn get_string_id_by_name(&self, s: &str) -> Option<StringId> {
get_string_id_by_name(&self.string_map, s)
}
/// Interns bytes, returning its `BytesId`.
///
/// Unlike interns, bytes are not deduplicated (bytes literals are rare).
pub fn intern_bytes(&mut self, b: &[u8]) -> BytesId {
let id = BytesId(self.bytes.len().try_into().expect("BytesId overflow"));
self.bytes.push(WithHash::for_bytes(b.to_vec()));
id
}
/// Interns a long integer, returning its `LongIntId`.
///
/// Big integers are not deduplicated since literals exceeding i64 are rare.
pub fn intern_long_int(&mut self, bi: BigInt) -> LongIntId {
let id = LongIntId(self.long_ints.len().try_into().expect("LongIntId overflow"));
self.long_ints.push(WithHash::for_long_int(bi));
id
}
/// Looks up a string by its `StringId`.
#[inline]
pub fn get_str(&self, id: StringId) -> &str {
get_str(&self.strings, id)
}
}
/// Interns `s` into a `string_map`/`strings` pair, shared by [`InternerBuilder`]
/// and [`Interns`] so both tables allocate ids identically.
///
/// Single-ASCII and [`StaticStrings`] values resolve to their reserved ids
/// without touching the pool; everything else is deduplicated via `string_map`.
fn intern_str(string_map: &mut AHashMap<String, StringId>, strings: &mut Vec<WithHash<String>>, s: &str) -> StringId {
if s.len() == 1 {View on GitHub (pinned to adc986b362)
Solutions
- Check why so many long integers are being interned without table reuse; recycle or reset the InternTable per compilation unit.
- Verify the ID type width (e.g. widen `LongIntId` to u64) if your workload legitimately interns enormous numbers of values.
- Report as a bug if reached with a normal workload.
Example fix
// before
let id = LongIntId(self.long_ints.len().try_into().expect("LongIntId overflow"));
// after
let id = LongIntId(u32::try_from(self.long_ints.len()).map_err(|_| CompileError::TooManyInternedValues)?); Defensive patterns
Strategy: validation
Validate before calling
assert!(intern_table.long_int_count() < u32::MAX as usize, "LongIntId space exhausted");
Prevention
- Recycle or reset the intern table per compilation unit
- Cap generated code size before compiling
- Treat any occurrence as an interpreter bug report
When it happens
Trigger: Calling `intern_long_int` (directly or via compiling/executing code with huge numbers of distinct >i64 integer literals) when `long_ints.len()` exceeds `u32::MAX` (or the backing integer width).
Common situations: Practically only hit by generated code containing billions of unique big-int literals, or a bug in table reuse/clearing that lets the table grow unboundedly.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- StringId overflow
- Invalid static string ID
- StringId overflow while building reverse interns map
- dict_keys view must reference a dict
- dict_items view must always reference a dict
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/5c0df0b9a9a23d5c.
Report an issue: GitHub.