{"record":{"id":"e478aeb2fa9f63d8","repo":"pydantic/monty","slug":"cannot-get-identity-of-dereferenced-object","errorCode":null,"errorMessage":"Cannot get identity of Dereferenced object","messagePattern":"Cannot get identity of Dereferenced object","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/monty/src/identity.rs","lineNumber":84,"sourceCode":"        match value {\n            Value::Undefined => Self::Undefined,\n            Value::Ellipsis => Self::Ellipsis,\n            Value::NotImplemented => Self::NotImplemented,\n            Value::None => Self::None,\n            Value::Bool(value) => Self::Bool(*value),\n            Value::Int(value) => Self::Int(*value),\n            Value::Float(value) => Self::Float(value.to_bits()),\n            Value::InternString(id) => Self::InternString(id.index()),\n            Value::InternBytes(id) => Self::InternBytes(id.index()),\n            Value::InternLongInt(id) => Self::InternLongInt(id.index()),\n            Value::Builtin(builtin) => Self::Builtin(*builtin),\n            Value::ModuleFunction(function) => Self::ModuleFunction(*function),\n            Value::DefFunction(id) => Self::DefFunction(id.index()),\n            Value::Marker(marker) => Self::Marker(*marker),\n            Value::Property(property) => Self::Property(*property),\n            Value::Ref(id) => Self::Heap(id.index()),\n            #[cfg(feature = \"memory-model-checks\")]\n            Value::Dereferenced => panic!(\"Cannot get identity of Dereferenced object\"),\n        }\n    }\n\n    /// Builds the identity of an arena-allocated object.\n    pub(crate) fn from_heap_id(id: HeapId) -> Self {\n        Self::Heap(id.index())\n    }\n\n    /// Encodes this key as the nonnegative integer exposed by Python's `id()`.\n    pub(crate) fn encoded(&self) -> u128 {\n        let payload = match self {\n            Self::Undefined | Self::Ellipsis | Self::NotImplemented | Self::None => 0,\n            Self::Bool(value) => u128::from(*value),\n            Self::Int(value) => u128::from(zigzag_i64(*value)),\n            Self::Float(bits) => u128::from(compact_float_bits(*bits)),\n            Self::InternString(index)\n            | Self::InternBytes(index)\n            | Self::InternLongInt(index)","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty/src/identity.rs#L66-L102","documentation":"Value::identity() panics when called on a Value::Dereferenced sentinel. Dereferenced is a memory-model-checks-only marker that replaces a value after its heap entry has been released; by design it has no identity. The panic asserts that no code path ever asks for the identity of a released object — hitting it means a value escaped the scope where dereferencing was recorded.","triggerScenarios":"Building an ObjectIdentity from a Value::Dereferenced while running with the `memory-model-checks` feature; a code path holds a Value after it was dereferenced and then computes its identity (e.g. for dict keys, `is` comparison, or hashing).","commonSituations":"Contributors running memory-model-checks CI after adding new opcodes or refcount paths; a new heap mutation path drops an entry but a stale Value is later used as an identity-bearing operand.","solutions":["Do not compute identity on values that may be Dereferenced — check the variant first and handle it explicitly.","Fix the refcount path that produced a stale Dereferenced value; the value should have been dropped or replaced before identity use.","Reproduce without the memory-model-checks feature; in release builds the variant does not exist, confirming it is a checks-only invariant.","Add a debug assertion or match arm upstream so Dereferenced never reaches identity computation."],"exampleFix":"// before\nlet identity = ObjectIdentity::new(&value);\n// after\nmatch value {\n    Value::Dereferenced => unreachable!(), // fix the stale-value path instead\n    _ => { let identity = ObjectIdentity::new(&value); }\n}","handlingStrategy":"type-guard","validationCode":"// before computing identity\nfn identity_safe(v: &Value) -> Option<ObjectIdentity> {\n    if matches!(v, Value::Dereferenced) { None } else { Some(ObjectIdentity::new(v)) }\n}","typeGuard":"fn is_dereferenced(v: &Value) -> bool { matches!(v, Value::Dereferenced) }","tryCatchPattern":null,"preventionTips":["Never hold Values across heap-entry release points","Run memory-model-checks CI on refcount-touching changes","Use defer_drop!/DropGuard so stale values cannot escape scopes"],"tags":["rust","internal-invariant","memory-model"],"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"}