pydantic/monty · error

dict_keys view must reference a dict

Error message

dict_keys view must reference a dict

What it means

This is an internal Rust panic in Monty's dict-keys view implementation. A DictKeysView holds a HeapId that must always point to a Dict heap entry; if `heap.read(dict_id)` returns anything else, a core data-structure invariant has been broken. Users should never see this in normal operation — it indicates a bug in the interpreter or in unsafe/misuse of the heap API.

Source

Thrown at crates/monty/src/types/dict_view.rs:167

    }
}

impl DictView for DictKeysView {
    fn dict_id(&self) -> HeapId {
        self.dict_id
    }
}

impl<'h> PyTrait<'h> for HeapObjectRead<'h, DictKeysView> {
    fn py_is_iterable(&self, _vm: &VM<'h>) -> bool {
        true
    }

    /// Delegates to the backing dict's key lookup.
    fn py_contains_impl(&self, item: &Value, vm: &mut VM<'h>) -> RunResult<Option<bool>> {
        let dict_id = self.get(vm.heap).dict_id();
        let HeapReadOutput::Dict(dict) = vm.heap.read(dict_id) else {
            panic!("dict_keys view must reference a dict");
        };
        dict.contains_key(item, vm).map(Some)
    }

    fn py_type(&self, _vm: &VM<'h>) -> Type {
        Type::DictKeys
    }

    fn py_iter(&self, vm: &mut VM<'h>) -> RunResult<Value> {
        let dict_id = self.get(vm.heap).dict_id();
        Ok(DictKeyIterator::allocate(
            dict_id,
            self.get(vm.heap).dict(vm.heap).len(),
            vm,
        ))
    }

    fn py_len(&self, vm: &VM<'h>) -> Option<usize> {

View on GitHub (pinned to adc986b362)

Solutions

  1. Report the triggering Python snippet and traceback to the Monty maintainers as a bug.
  2. Audit code that creates DictKeysView or mutates/frees heap entries to ensure dict_id is always a live Dict.
  3. Check recent changes to heap.rs, dict_view.rs, or cycle collection that could orphan or retarget the view's dict_id.

Example fix

// before
let HeapReadOutput::Dict(dict) = vm.heap.read(dict_id) else {
    panic!("dict_keys view must reference a dict");
};
// after (hardening, not a user fix): log diagnostics before panicking
let HeapReadOutput::Dict(dict) = vm.heap.read(dict_id) else {
    debug_assert!(false, "dict_keys view dict_id {dict_id:?} is not a Dict");
    panic!("dict_keys view must reference a dict");
};
Defensive patterns

Strategy: try-catch

Try / catch

// Rust host code catching a worker panic
catch_unwind(|| run_monty_code(source)).unwrap_or_else(|_| {
    eprintln!("internal monty panic: dict_keys view invariant broken; please report this bug");
    Err(MontyError::internal())
})

Prevention

When it happens

Trigger: Calling membership operations (`in`) on a `dict.keys()` view when the view's `dict_id` no longer resolves to a Dict entry in the heap — only reachable through an interpreter bug, heap corruption, or a stale HeapId after an incorrect dec_ref.

Common situations: Hit by Monty contributors while modifying heap lifecycle, view construction, or cycle-collection code; not reachable from sandboxed Python code under correct operation.

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


AI-assisted analysis of pydantic/monty@adc986b362 (2026-09-13). Data as JSON: /api/errors/62172559721516af. Report an issue: GitHub.