{"record":{"id":"2749b69486e0dd3f","repo":"pydantic/monty","slug":"dict-values-view-must-reference-a-dict","errorCode":null,"errorMessage":"dict_values view must reference a dict","messagePattern":"dict_values view must reference a dict","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/monty/src/types/dict_view.rs","lineNumber":591,"sourceCode":"impl<'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);\n        while let Some(value) = iter.next_value(vm)? {\n            // Stored value on the left, matching CPython's iteration fallback.\n            if value.py_eq(item, vm)? {\n                return Ok(Some(true));\n            }\n        }\n        Ok(Some(false))\n    }\n\n    fn py_type(&self, _vm: &VM<'h>) -> Type {\n        Type::DictValues\n    }\n\n    fn py_iter(&self, vm: &mut VM<'h>) -> RunResult<Value> {\n        let dict_id = self.get(vm.heap).dict_id();","sourceCodeStart":573,"sourceCodeEnd":609,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty/src/types/dict_view.rs#L573-L609","documentation":"Internal panic in the dict-values view `py_contains_impl`, which implements `value in dict.values()`. The view's dict_id must resolve to a Dict before the linear scan; any other heap variant means a core invariant was violated. Not reachable from correct Python code.","triggerScenarios":"Evaluating `x in dict.values()` when the values view's dict_id resolves to a non-Dict heap entry — only through an interpreter bug, stale HeapId, or heap corruption.","commonSituations":"Encountered by Monty developers modifying heap lifecycle or view code; sandboxed Python users should never trigger it.","solutions":["File a bug report with the reproducing script and panic output.","Audit how the view's dict_id was created and whether the dict entry could have been freed and reused.","Verify `py_dec_ref_ids` ownership of the dict_id field on DictValuesView."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let HeapReadOutput::Dict(dict) = vm.heap.read(dict_id) else {\n    return Err(internal_error(\"dict_values view must reference a dict\"));\n};","preventionTips":["Document dict_id fields as owned and verify single-release cleanup.","Test `x in d.values()` in view test suites after heap refactors.","Check cycle-collection behavior for views referencing dicts."],"tags":["rust","internal-error","panic","dict-view","membership-test"],"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"}