{"record":{"id":"576aecb50d4a8cd4","repo":"pydantic/monty","slug":"dict-values-view-must-always-reference-a-dict","errorCode":null,"errorMessage":"dict_values view must always reference a dict","messagePattern":"dict_values view must always reference a dict","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/monty/src/types/dict_view.rs","lineNumber":576,"sourceCode":"    }\n\n    /// Returns the underlying dictionary heap id.\n    #[must_use]\n    pub fn dict_id(self) -> HeapId {\n        self.dict_id\n    }\n}\n\nimpl DictView for DictValuesView {\n    fn dict_id(&self) -> HeapId {\n        self.dict_id\n    }\n}\n\nimpl<'h> HeapRead<'h, DictValuesView> {\n    fn dict(&self, vm: &mut VM<'h>) -> HeapObjectRead<'h, Dict> {\n        let HeapReadOutput::Dict(dict) = vm.heap.read(self.get(vm.heap).dict_id) else {\n            panic!(\"dict_values view must always reference a dict\");\n        };\n        dict\n    }\n}\n\nimpl<'h> PyTrait<'h> for HeapObjectRead<'h, DictValuesView> {\n    fn py_is_iterable(&self, _vm: &VM<'h>) -> bool {\n        true\n    }\n\n    /// Values are not indexed, so this is a linear scan of the backing dict.\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_values view must reference a dict\");\n        };\n        let iter = dict.iter(vm)?;\n        defer_drop_mut!(iter, vm);","sourceCodeStart":558,"sourceCodeEnd":594,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty/src/types/dict_view.rs#L558-L594","documentation":"Internal panic in the `DictValuesView::dict()` helper: a dict-values view must always reference a Dict heap entry via its `dict_id`. The panic fires if the read returns any other heap object variant, meaning the view invariant is broken. This is not a user-facing error.","triggerScenarios":"Any values-view operation that resolves the backing dict through the private `dict()` accessor (iteration, `len`, `contains`) when the stored dict_id resolves to a non-Dict entry — only via interpreter bugs or heap corruption.","commonSituations":"Hit by Monty contributors while changing heap allocation, view construction, or refcount handling; not reachable from sandboxed Python under correct operation.","solutions":["Report the failing script and panic message to Monty maintainers.","Check that DictValuesView is only constructed with a live Dict HeapId.","Run the memory-model-checks feature over the relevant tests to hunt refcount bugs."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match vm.heap.read(dict_id) {\n    HeapReadOutput::Dict(d) => d,\n    _ => return Err(internal_error(\"dict_values view lost its backing dict\")),\n}","preventionTips":["Ensure DictValuesView construction always stores a live Dict HeapId.","Run memory-model-checks on view-related tests when modifying the heap.","Do not free the backing dict while a view can still be reached from Python."],"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-14T16:17:12.679Z"}