pydantic/monty · error
test function has an owned cell
Error message
test function has an owned cell
What it means
This panic comes from an `expect` in `FunctionMetadata::corrupt_metadata_for_tests`, a test-only fault injector that deliberately corrupts function metadata to test deserializer validation. It fires when the `CellVarLengthMismatch` fault is requested but the target function metadata has no cell param indices to pop, meaning the test fixture was built without an owned cell variable. It indicates the test setup, not the code under test, is wrong.
Source
Thrown at crates/monty/src/function.rs:322
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;
}
FunctionMetadataFault::CellParamIndexOutOfRange => {
*self
.cell_param_indicesView on GitHub (pinned to adc986b362)
Solutions
- Fix the test fixture so the function metadata actually contains a cell param index before applying the fault (compile a function with a closure capturing a cell).
- Pick a different fault variant applicable to metadata that exists (e.g. namespace-size faults).
- Guard the fault application with an `if !self.cell_param_indices.is_empty()` check in the fault injector or skip the case in the test matrix.
Example fix
// before
fn fixture() -> FunctionMetadata { /* function without cells */ make_metadata('f') }
let mut m = fixture();
m.corrupt_metadata_for_tests(FunctionMetadataFault::CellVarLengthMismatch); // panics
// after
let mut m = make_metadata_with_cell('f'); // function capturing a cell variable
m.corrupt_metadata_for_tests(FunctionMetadataFault::CellVarLengthMismatch); Defensive patterns
Strategy: validation
Validate before calling
assert!(!metadata.cell_param_indices.is_empty(), 'fixture must have a cell param for CellVarLengthMismatch');
Prevention
- Build fixtures that satisfy every fault's preconditions (cells, free vars, cell params).
- Apply faults to fresh clones, never stacked.
- Keep fault applicability checks inside the injector where possible.
When it happens
Trigger: Calling `corrupt_metadata_for_tests(FunctionMetadataFault::CellVarLengthMismatch)` on function metadata whose `cell_param_indices` vec is empty (a function compiled without cell variables).
Common situations: Writing a new roundtrip/deserialization fuzz or fault test against a helper function that has no closures or cell variables; refactoring a test fixture so the function no longer captures cells while the fault list still assumes one.
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
- test namespace fits in u16
- entry just allocated
- gather commit frame id is not a GatherFuture
- gather item is not a Coroutine, ExternalFuture, or GatherFut
- Cannot get identity of Dereferenced object
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/77bc99185cf48b46.
Report an issue: GitHub.