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

  1. Check the exact function name as it appears in the test's Python source (including case).
  2. Ensure the code defining the function is prepared/compiled before calling the hook.
  3. Verify the `test-hooks` feature is enabled on the build, so the hook and its metadata path match.
  4. 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

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


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)