pydantic/monty · error
test function has a free variable
Error message
test function has a free variable
What it means
A panic raised by the memory-model test fault injector in `FunctionMetadata::corrupt_metadata_for_tests`. The `FreeVarLengthMismatch` fault pops a slot from `free_var_slots`, which only works when the function actually has free variables; `.expect("test function has a free variable")` panics when the list is empty. This is a test-harness bug (wrong fault kind applied to a function with no free vars), not a runtime error users can hit.
Source
Thrown at crates/monty/src/function.rs:319
}
})
} else {
None
}
}
/// Injects a metadata fault for dump validation tests.
#[cfg(feature = "test-hooks")]
pub(crate) fn corrupt_metadata_for_tests(&mut self, fault: FunctionMetadataFault) {
match fault {
FunctionMetadataFault::SignatureSlotsBeyondNamespace => {
self.namespace_size = self.signature.total_slots() - 1;
}
FunctionMetadataFault::NamespaceTooLarge => {
self.namespace_size = usize::from(u16::MAX) + 1;
}
FunctionMetadataFault::FreeVarLengthMismatch => {
self.free_var_slots.pop().expect("test function has a free variable");
}
FunctionMetadataFault::CellVarLengthMismatch => {
self.cell_param_indices.pop().expect("test function has an owned cell");
}
FunctionMetadataFault::FreeVarSlotOutOfRange => {
let slot = NamespaceId::new(self.namespace_size).expect("test namespace fits in u16");
*self
.free_var_slots
.first_mut()
.expect("test function has a free variable") = slot;
}
FunctionMetadataFault::CellVarSlotOutOfRange => {
let slot = NamespaceId::new(self.namespace_size).expect("test namespace fits in u16");
*self
.cell_var_slots
.first_mut()
.expect("test function has an owned cell") = slot;
}View on GitHub (pinned to adc986b362)
Solutions
- Point the fault injection at a test function that closes over at least one free variable
- Choose a different `FunctionMetadataFault` variant appropriate to the function's actual metadata
- Guard the fault site: skip or fall back to another fault when `free_var_slots` is empty
Example fix
// before
FunctionMetadataFault::FreeVarLengthMismatch => {
self.free_var_slots.pop().expect("test function has a free variable");
}
// after (test selection side)
let func = funcs.iter().find(|f| !f.free_var_slots.is_empty())
.expect("fixture must include a function with free vars");
func.corrupt_metadata_for_tests(FunctionMetadataFault::FreeVarLengthMismatch); Defensive patterns
Strategy: validation
Validate before calling
// Only apply FreeVarLengthMismatch to functions that have free variables.
fn can_inject(fault: Fault, meta: &FunctionMetadata) -> bool {
match fault {
Fault::FreeVarLengthMismatch => !meta.free_var_slots.is_empty(),
Fault::CellVarLengthMismatch => !meta.cell_param_indices.is_empty(),
_ => true,
}
} Prevention
- Pick fault fixtures whose metadata actually contains the field the fault mutates
- Add a fixture function with at least one closure capture for free-var faults
- Prefer skipping an inapplicable fault over expect()-panicking in test helpers
When it happens
Trigger: Calling `corrupt_metadata_for_tests` with `FunctionMetadataFault::FreeVarLengthMismatch` on a `FunctionMetadata` whose `free_var_slots` vector is empty (e.g. a function with no closure captures).
Common situations: Writing a new memory-model/refcount test that applies the fault to a fixture function that has no free variables, or reusing a fault helper against a simplified test function.
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
- dict_keys view must reference a dict
- dict_items view must always reference a dict
- dict_items view must reference a dict
- dict_values view must always reference a dict
- dict_values view must reference a dict
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/7981122301552a28.
Report an issue: GitHub.