xai-org/x-algorithm · error
Not implemented: to_thrift for SafetyResult
Error message
Not implemented: to_thrift for SafetyResult
What it means
SafetyResult implements only the Thrift decode half of MValCodec; to_thrift panics because serialization was never needed for this type. The panic documents an intentional hole in the codec implementation rather than a runtime condition.
Source
Thrown at visibility-filtering-client/models.rs:192
32 => SafetyResultReason::GoreAndViolenceHighPrecision,
_ => SafetyResultReason::Episodic,
});
}
Some(2) => {
action = Action::from_thrift(proto);
}
_ => {
proto.skip(field.field_type).unwrap();
}
}
proto.read_field_end().unwrap();
}
proto.read_struct_end().unwrap();
SafetyResult { reason, action }
}
fn to_thrift(&self, _proto: &mut dyn TOutputProtocol) {
panic!("Not implemented: to_thrift for SafetyResult")
}
}
impl MValCodec for Action {
fn thrift_type() -> TType {
TType::Struct
}
fn from_thrift(proto: &mut dyn TInputProtocol) -> Self {
proto.read_struct_begin().unwrap();
let mut result = Action::NotEvaluated;
loop {
let field = proto.read_field_begin().unwrap();
if field.field_type == TType::Stop {
break;
}
match field.id {
Some(1) => {View on GitHub (pinned to 24c60942c5)
Solutions
- Avoid encoding SafetyResult; consume it via from_thrift only.
- Implement to_thrift mirroring the decoder: write 'reason' and 'action' fields with the same field ids/types the reader expects.
- Serialize an equivalent protobuf type if one exists instead of the Thrift codec.
Example fix
// before
fn to_thrift(&self, _proto: &mut dyn TOutputProtocol) {
panic!("Not implemented: to_thrift for SafetyResult")
}
// after: mirror the reader's field ids (1: reason, 2: action)
fn to_thrift(&self, proto: &mut dyn TOutputProtocol) {
proto.write_struct_begin(&TStructIdentifier::new("SafetyResult")).unwrap();
self.reason.write_field(proto, 1);
self.action.write_field(proto, 2);
proto.write_field_stop().unwrap();
proto.write_struct_end().unwrap();
} Defensive patterns
Strategy: type-guard
Type guard
trait WriteCodec { fn to_thrift(&self, p: &mut dyn TOutputProtocol); }
fn encode<T: WriteCodec>(v: &T, p: &mut dyn TOutputProtocol) { v.to_thrift(p); }
// SafetyResult: encode via this fn is a compile error until implemented Try / catch
let r = std::panic::catch_unwind(|| sr.to_thrift(proto));
if r.is_err() { /* log and serialize the protobuf equivalent instead */ } Prevention
- Use capability traits (WriteCodec/ReadCodec) instead of one MValCodec with panicking halves.
- Avoid generic 'encode anything' utilities over codec impls.
- Add unit tests that assert which types are encodeable.
When it happens
Trigger: Serializing a SafetyResult (reason + action fields) to Thrift: writing it to a log/mval sink, sending it over a Thrift service, or a generic encode path / round-trip test that invokes to_thrift.
Common situations: New feature code starts emitting SafetyResult over the wire or into storage; generic codec utilities that encode every MValCodec type; test harnesses that verify symmetry between from_thrift and to_thrift.
Related errors
- Not implemented: to_thrift for KeywordMatch
- Not implemented: to_thrift for Action
- Not implemented: to_thrift for DropReason
- Not implemented: to_thrift for FilteredReason
- LookupContext should not be decoded from Thrift
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/7943a9e6fa0b60fc.
Report an issue: GitHub.