{"record":{"id":"055d1edd43a443d3","repo":"pydantic/monty","slug":"classinstancebody-is-decode-only","errorCode":null,"errorMessage":"ClassInstanceBody is decode-only","messagePattern":"ClassInstanceBody is decode-only","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/monty-proto/src/wire.rs","lineNumber":1066,"sourceCode":"            1 => encoding::message::merge(\n                wire_type,\n                self.class_type.get_or_insert_with(TypeBody::default),\n                buf,\n                ctx,\n            ),\n            2 => encoding::message::merge(\n                wire_type,\n                self.instance_id.get_or_insert_with(pb::Uuid::default),\n                buf,\n                ctx,\n            ),\n            3 => encoding::message::merge(wire_type, self.attrs.get_or_insert_with(PairList::default), buf, ctx),\n            _ => skip_field(wire_type, tag, buf, ctx),\n        }\n    }\n\n    fn encode_raw(&self, _buf: &mut impl BufMut) {\n        unreachable!(\"ClassInstanceBody is decode-only\")\n    }\n\n    fn encoded_len(&self) -> usize {\n        unreachable!(\"ClassInstanceBody is decode-only\")\n    }\n\n    fn clear(&mut self) {\n        self.class_type = None;\n        self.instance_id = None;\n        self.attrs = None;\n    }\n}\n\n/// Maps a semantic validation failure onto prost's decode error so it\n/// surfaces through the normal frame-decode path.\n//\n// `DecodeError::new` is deprecated but has no public replacement in prost\n// 0.14 (`DecodeErrorKind` is crate-private); the deprecation note itself","sourceCodeStart":1048,"sourceCodeEnd":1084,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-proto/src/wire.rs#L1048-L1084","documentation":"`ClassInstanceBody` is another decode-only hand-written prost `Message` impl in wire.rs: its `encode_raw` panics with `unreachable!(\"ClassInstanceBody is decode-only\")`. The struct exists purely to decode class-instance values from the wire; it is never meant to be serialized. Hitting the panic means an encode path reached a decode-only type.","triggerScenarios":"Serializing a MontyObject representing a class instance (with `class_type`, `instance_id`, `attrs`) through the hand-written `ClassInstanceBody` Message impl — e.g. a worker trying to send a class-instance value back to the parent via this body type.","commonSituations":"Extending the wire protocol to round-trip new object kinds and accidentally routing class instances into the decode-only struct on the encode side; refactoring `WireObject` conversions so encode and decode no longer use mirrored types.","solutions":["Encode class-instance values through the designated encode representation, never through `ClassInstanceBody`.","If class instances must be encoded, implement real `encode_raw`/`encoded_len` (fields: class_type, instance_id, attrs PairList) or regenerate a prost message for both directions.","Run `make check-proto` to confirm the wire schema and hand-written impls stayed in sync.","Replace the value with an encodable representation before sending."],"exampleFix":"// before\nfn encode_raw(&self, _buf: &mut impl BufMut) { unreachable!(\"ClassInstanceBody is decode-only\") }\n// after\nfn encode_raw(&self, buf: &mut impl BufMut) {\n    if let Some(t) = &self.class_type { encoding::message::encode(...); }\n    // ...\n}","handlingStrategy":"validation","validationCode":"// Rust: ensure class instances are encoded via the supported representation\nassert!(encodable(value), \"ClassInstanceBody is decode-only; use the encode path for class instances\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat ClassInstanceBody strictly as a decode target; encode class instances with the mirrored generated message.","Add encode/decode round-trip tests for class-instance values.","Run make check-proto in CI before merging wire changes."],"tags":["protobuf","wire-protocol","internal-panic"],"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"}