{"record":{"id":"62172559721516af","repo":"pydantic/monty","slug":"dict-keys-view-must-reference-a-dict","errorCode":null,"errorMessage":"dict_keys view must reference a dict","messagePattern":"dict_keys view must reference a dict","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/monty/src/types/dict_view.rs","lineNumber":167,"sourceCode":"    }\n}\n\nimpl DictView for DictKeysView {\n    fn dict_id(&self) -> HeapId {\n        self.dict_id\n    }\n}\n\nimpl<'h> PyTrait<'h> for HeapObjectRead<'h, DictKeysView> {\n    fn py_is_iterable(&self, _vm: &VM<'h>) -> bool {\n        true\n    }\n\n    /// Delegates to the backing dict's key lookup.\n    fn py_contains_impl(&self, item: &Value, vm: &mut VM<'h>) -> RunResult<Option<bool>> {\n        let dict_id = self.get(vm.heap).dict_id();\n        let HeapReadOutput::Dict(dict) = vm.heap.read(dict_id) else {\n            panic!(\"dict_keys view must reference a dict\");\n        };\n        dict.contains_key(item, vm).map(Some)\n    }\n\n    fn py_type(&self, _vm: &VM<'h>) -> Type {\n        Type::DictKeys\n    }\n\n    fn py_iter(&self, vm: &mut VM<'h>) -> RunResult<Value> {\n        let dict_id = self.get(vm.heap).dict_id();\n        Ok(DictKeyIterator::allocate(\n            dict_id,\n            self.get(vm.heap).dict(vm.heap).len(),\n            vm,\n        ))\n    }\n\n    fn py_len(&self, vm: &VM<'h>) -> Option<usize> {","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty/src/types/dict_view.rs#L149-L185","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hit by Monty contributors while modifying heap lifecycle, view construction, or cycle-collection code; not reachable from sandboxed Python code under correct operation.","solutions":["Report the triggering Python snippet and traceback to the Monty maintainers as a bug.","Audit code that creates DictKeysView or mutates/frees heap entries to ensure dict_id is always a live Dict.","Check recent changes to heap.rs, dict_view.rs, or cycle collection that could orphan or retarget the view's dict_id."],"exampleFix":"// before\nlet HeapReadOutput::Dict(dict) = vm.heap.read(dict_id) else {\n    panic!(\"dict_keys view must reference a dict\");\n};\n// after (hardening, not a user fix): log diagnostics before panicking\nlet HeapReadOutput::Dict(dict) = vm.heap.read(dict_id) else {\n    debug_assert!(false, \"dict_keys view dict_id {dict_id:?} is not a Dict\");\n    panic!(\"dict_keys view must reference a dict\");\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Rust host code catching a worker panic\ncatch_unwind(|| run_monty_code(source)).unwrap_or_else(|_| {\n    eprintln!(\"internal monty panic: dict_keys view invariant broken; please report this bug\");\n    Err(MontyError::internal())\n})","preventionTips":["Keep dict view HeapId fields documented as owned and release them exactly once via py_dec_ref_ids.","Run memory-model-checks tests when touching heap or view lifecycle code.","Never reuse or reassign a view's dict_id after construction."],"tags":["rust","internal-error","panic","dict-view"],"backgroundTag":"internal-invariant-violation","analyzedSha":"adc986b362e3961f407868cb118a99fe831b9e61","analyzedAt":"2026-09-13T19:19:18.698Z","contentChangedAt":"2026-09-13T19:19:18.698Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}