{"record":{"id":"ff3cb6fdaa9986fb","repo":"xai-org/x-algorithm","slug":"not-implemented-to-thrift-for-keywordmatch","errorCode":null,"errorMessage":"Not implemented: to_thrift for KeywordMatch","messagePattern":"Not implemented: to_thrift for KeywordMatch","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"visibility-filtering-client/models.rs","lineNumber":121,"sourceCode":"            if field.field_type == TType::Stop {\n                break;\n            }\n            match field.id {\n                Some(1) => {\n                    keyword = proto.read_string().unwrap();\n                }\n                _ => {\n                    proto.skip(field.field_type).unwrap();\n                }\n            }\n            proto.read_field_end().unwrap();\n        }\n        proto.read_struct_end().unwrap();\n        KeywordMatch { keyword }\n    }\n\n    fn to_thrift(&self, _proto: &mut dyn TOutputProtocol) {\n        panic!(\"Not implemented: to_thrift for KeywordMatch\")\n    }\n}\n\nimpl MValCodec for SafetyResult {\n    fn thrift_type() -> TType {\n        TType::Struct\n    }\n\n    fn from_thrift(proto: &mut dyn TInputProtocol) -> Self {\n        proto.read_struct_begin().unwrap();\n        let mut reason: Option<SafetyResultReason> = None;\n        let mut action = Action::default();\n        loop {\n            let field = proto.read_field_begin().unwrap();\n            if field.field_type == TType::Stop {\n                break;\n            }\n            match field.id {","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/visibility-filtering-client/models.rs#L103-L139","documentation":"The MValCodec trait requires both from_thrift and to_thrift, but KeywordMatch only implements Thrift decoding (reading). Serialization was intentionally left unimplemented, so calling to_thrift on a KeywordMatch panics immediately. This is a developer-facing assertion that the type is decode-only in the visibility-filtering client.","triggerScenarios":"Any code path that serializes a KeywordMatch to Thrift — e.g. writing it into an MVal (manhattan value) column, forwarding it over a Thrift RPC, or a generic codec function that calls to_thrift on MValCodec types. Also hit in tests that round-trip encode/decode.","commonSituations":"A new caller starts persisting KeywordMatch structs, a generic serializer iterates all MValCodec impls, or someone writes a round-trip unit test without noticing the encode side is unimplemented.","solutions":["Stop calling to_thrift on KeywordMatch; this type is decode-only by design.","If you own the model, implement to_thrift (mirror the field writes of the matching from_thrift reader, writing the 'keyword' string field).","Convert to the protobuf type vf_pb::KeywordMatch (a From impl exists) and serialize that instead.","If serialization is genuinely never needed, add a compile-time guard or code comment so generic encoders exclude decode-only types."],"exampleFix":"// before\nfn to_thrift(&self, _proto: &mut dyn TOutputProtocol) {\n    panic!(\"Not implemented: to_thrift for KeywordMatch\")\n}\n\n// after\nfn to_thrift(&self, proto: &mut dyn TOutputProtocol) {\n    let ident = TStructIdentifier::new(\"KeywordMatch\");\n    proto.write_struct_begin(&ident).unwrap();\n    proto.write_field_begin(&TFieldIdentifier::new(\"keyword\", TType::String, 1)).unwrap();\n    proto.write_string(&self.keyword).unwrap();\n    proto.write_field_end().unwrap();\n    proto.write_field_stop().unwrap();\n    proto.write_struct_end().unwrap();\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Trait-level capability split: only encode types that implement WriteCodec\ntrait WriteCodec { fn to_thrift(&self, p: &mut dyn TOutputProtocol); }\nfn encode<T: WriteCodec>(v: &T, p: &mut dyn TOutputProtocol) { v.to_thrift(p); }\n// KeywordMatch simply does not implement WriteCodec, so this call won't compile","tryCatchPattern":"let r = std::panic::catch_unwind(|| m.to_thrift(proto));\nif r.is_err() { /* fall back to vf_pb::KeywordMatch serialization */ }","preventionTips":["Split codec traits into read-only and write-only capabilities so encode-only/decode-only types are compile-time enforced.","Keep round-trip codec tests parameterized by direction so they skip one-sided impls.","Document decode-only types with rustdoc warnings."],"tags":["rust","thrift","serialization","codec","visibility-filtering","not-implemented"],"backgroundTag":"thrift-unimplemented-serializer","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}