{"record":{"id":"efd794fad087356e","repo":"xai-org/x-algorithm","slug":"lookupcontext-should-not-be-decoded-from-thrift","errorCode":null,"errorMessage":"LookupContext should not be decoded from Thrift","messagePattern":"LookupContext should not be decoded from Thrift","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"visibility-filtering-client/vf_client.rs","lineNumber":71,"sourceCode":"            _ => None,\n        }\n    }\n}\n\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]\n#[serde(rename_all = \"camelCase\")]\npub struct VisibilityFilteringLookupContext {\n    pub safety_level: SafetyLevel,\n    pub for_user_id: u64,\n}\n\nimpl MValCodec for VisibilityFilteringLookupContext {\n    fn thrift_type() -> TType {\n        TType::Struct\n    }\n\n    fn from_thrift(_proto: &mut dyn TInputProtocol) -> Self {\n        panic!(\"LookupContext should not be decoded from Thrift\")\n    }\n\n    fn to_thrift(&self, proto: &mut dyn TOutputProtocol) {\n        let struct_id = TStructIdentifier::new(\"VisibilityFilteringLookupContext\");\n        proto.write_struct_begin(&struct_id).unwrap();\n        proto\n            .write_field_begin(&TFieldIdentifier::new(\"safety_level\", TType::I32, 1))\n            .unwrap();\n        self.safety_level.to_thrift(proto);\n        proto.write_field_end().unwrap();\n        proto\n            .write_field_begin(&TFieldIdentifier::new(\"for_user_id\", TType::I64, 2))\n            .unwrap();\n        proto.write_i64(self.for_user_id as i64).unwrap();\n        proto.write_field_end().unwrap();\n        proto.write_field_stop().unwrap();\n        proto.write_struct_end().unwrap();\n    }","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/visibility-filtering-client/vf_client.rs#L53-L89","documentation":"VisibilityFilteringLookupContext is constructed programmatically from query fields and only ever serialized (to_thrift); decoding it back from Thrift is meaningless, so from_thrift panics as an explicit guard. The lookup context is request-side data, not a response type.","triggerScenarios":"Calling MValCodec::from_thrift on VisibilityFilteringLookupContext — e.g. a generic Thrift reader, a round-trip test, or deserializing a captured request payload back into the context type.","commonSituations":"Codec conformance tests that round-trip every MValCodec type; generic decode utilities; attempts to reconstruct request context from logged Thrift bytes.","solutions":["Remove the decode path; construct VisibilityFilteringLookupContext from its builder/query fields instead.","If a round-trip is required for tests, skip decode-only/encode-only types via a marker or capability flag.","Parse the underlying query fields directly rather than decoding the serialized context."],"exampleFix":"// before\nfn from_thrift(_proto: &mut dyn TInputProtocol) -> Self {\n    panic!(\"LookupContext should not be decoded from Thrift\")\n}\n\n// after: fail fast with a clear error instead of aborting the process\nfn from_thrift(_proto: &mut dyn TInputProtocol) -> Self {\n    unimplemented!(\"LookupContext must be built from query fields, not decoded\")\n}\n// better: change the trait to split ReadCodec / WriteCodec so this arm cannot be reached","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"trait ReadCodec { fn from_thrift(p: &mut dyn TInputProtocol) -> Self; }\nfn decode<T: ReadCodec>(p: &mut dyn TInputProtocol) -> T { T::from_thrift(p) }\n// VisibilityFilteringLookupContext does not implement ReadCodec -> decode is a compile error","tryCatchPattern":"if std::panic::catch_unwind(|| VisibilityFilteringLookupContext::from_thrift(proto)).is_err() { /* rebuild context from query fields instead */ }","preventionTips":["Never deserialize request contexts from wire bytes; rebuild from source query data.","Split codec traits so decode-only/encode-only types are compiler-enforced.","Excluded encode-only types from round-trip test matrices."],"tags":["rust","thrift","deserialization","codec","visibility-filtering","encode-only"],"backgroundTag":"thrift-unimplemented-deserializer","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}