pydantic/monty · error
test function ' ' not found
Error message
test function '{name}' not found What it means
A test-only hook that deliberately corrupts function metadata must be told which Python-level function name to corrupt; if no interned function in the VM has that name, the hook panics. It is a test-harness lookup failure, not a runtime error user code can hit.
Solutions
- Check the exact function name as it appears in the test's Python source (including case).
- Ensure the code defining the function is prepared/compiled before calling the hook.
- Verify the `test-hooks` feature is enabled on the build, so the hook and its metadata path match.
- Enumerate `vm.functions` names in a debug print to see available candidates.
Example fix
// before
vm.corrupt_function_metadata_for_tests('frube', FunctionMetadataFault::BadCode);
// after
vm.corrupt_function_metadata_for_tests('frobnicate', FunctionMetadataFault::BadCode); Defensive patterns
Strategy: validation
Validate before calling
// in tests, before calling the hook
let names: Vec<String> = vm.functions.iter().map(|f| vm.get_str(f.name.name_id).to_owned()).collect();
assert!(names.iter().any(|n| n == name), 'function {name} not prepared'); Prevention
- Compile/prepare the Python code before invoking test hooks
- Copy function names exactly from the test source
- Add a helper listing prepared function names when a hook lookup fails
When it happens
Trigger: Calling `vm.corrupt_function_metadata_for_tests(name, fault)` under the `test-hooks` feature with a name that matches no function currently prepared in the VM (typo, function never defined, or defined after the call).
Common situations: Writing or renaming fault-injection tests for function metadata; test setup order changed so the function isn't compiled yet when the hook runs.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- already looked up
- `at_most_total` cannot be combined with `style = def` or…
- `at_most_total` cannot be combined with `varargs` or…
- `bad_arg`/`bad_arg_named` cannot be combined with `style =…
- bubble-up captured ' ' that is bound nowhere — scope…
AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13).
Data as JSON: /api/errors/60fdf690e158418c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/monty/src/intern.rs:1671
/// Lookup a function by its `FunctionId`
///
/// # Panics
///
/// Panics if the `FunctionId` is invalid.
#[inline]
pub fn get_function(&self, id: FunctionId) -> &Function {
self.functions.get(id.index()).expect("Function not found")
}
/// Injects `fault` into the named function's metadata.
#[cfg(feature = "test-hooks")]
pub(crate) fn corrupt_function_metadata_for_tests(&mut self, name: &str, fault: FunctionMetadataFault) {
let index = self
.functions
.iter()
.position(|function| self.get_str(function.name.name_id) == name)
.unwrap_or_else(|| panic!("test function '{name}' not found"));
self.functions[index].corrupt_metadata_for_tests(fault);
}
/// Returns the Python hash for an interned string.
///
/// Dispatches by id range:
/// * ASCII (`id < 128`): looks up [`ASCII_HASHES`] (per-slot lazy);
/// computes via [`hash_python_str`] on first use of that byte.
/// * Static (`id < INTERN_STRING_ID_OFFSET`): looks up [`STATIC_HASHES`]
/// (per-slot lazy); computes from the variant's `&'static str` on
/// first use of that variant.
/// * Interned (`id >= INTERN_STRING_ID_OFFSET`): reads the [`HashValue`]
/// from the corresponding [`WithHash`] entry — populated eagerly at
/// intern time.
///
/// All three paths must agree with [`hash_python_str`] applied to the
/// underlying `&str` — interned and heap strings with equal contents
/// must hash identically.View on GitHub (pinned to adc986b362)