xai-org/x-algorithm · error
QueryFields should not be decoded from Thrift
Error message
QueryFields should not be decoded from Thrift
What it means
SafetyLevel is encoded as a Thrift i32 (write side only); from_thrift panics because the type was never meant to be read back from Thrift. The panic message mentions QueryFields, hinting this decode path was copied from a sibling encode-only type and is intentionally unreachable.
Source
Thrown at visibility-filtering-client/vf_client.rs:98
self.safety_level.to_thrift(proto);
proto.write_field_end().unwrap();
proto
.write_field_begin(&TFieldIdentifier::new("for_user_id", TType::I64, 2))
.unwrap();
proto.write_i64(self.for_user_id as i64).unwrap();
proto.write_field_end().unwrap();
proto.write_field_stop().unwrap();
proto.write_struct_end().unwrap();
}
}
impl MValCodec for SafetyLevel {
fn thrift_type() -> TType {
TType::I32
}
fn from_thrift(_proto: &mut dyn TInputProtocol) -> Self {
panic!("QueryFields should not be decoded from Thrift")
}
fn to_thrift(&self, proto: &mut dyn TOutputProtocol) {
proto.write_i32(self.clone() as i32).unwrap();
}
}
#[async_trait]
pub trait VfClient {
async fn get_result(
&self,
post_ids: Vec<u64>,
safety_level: SafetyLevel,
for_user_id: u64,
context: Option<TwitterContextViewer>,
) -> HashMap<u64, Result<Option<FilteredReason>>>;
}
View on GitHub (pinned to 24c60942c5)
Solutions
- Do not decode SafetyLevel from Thrift; derive it from the response/query data that produced it.
- If decoding is genuinely needed, implement from_thrift as proto.read_i32().unwrap().try_into() with proper error handling.
- Split the codec trait into read-only/write-only capabilities so the compiler prevents this call.
Example fix
// before
fn from_thrift(_proto: &mut dyn TInputProtocol) -> Self {
panic!("QueryFields should not be decoded from Thrift")
}
// after (if decoding becomes necessary)
fn from_thrift(proto: &mut dyn TInputProtocol) -> Self {
let raw = proto.read_i32().unwrap();
SafetyLevel::try_from(raw).unwrap_or(SafetyLevel::default())
} Defensive patterns
Strategy: type-guard
Type guard
trait ReadCodec { fn from_thrift(p: &mut dyn TInputProtocol) -> Self; }
// SafetyLevel lacks ReadCodec; accidental decode fails to compile Try / catch
if std::panic::catch_unwind(|| SafetyLevel::from_thrift(proto)).is_err() { /* recompute SafetyLevel from response metadata */ } Prevention
- Derive SafetyLevel from authoritative query/response data, not serialized bytes.
- Use directional codec traits.
- In replay tooling, parse the i32 explicitly instead of the codec.
When it happens
Trigger: Invoking MValCodec::from_thrift on SafetyLevel — generic decode utilities, round-trip codec tests, or reading captured Thrift bytes that contain the encoded i32.
Common situations: Symmetric codec test suites; refactors that decode previously write-only values; logging/replay tooling that deserializes emitted payloads.
Related errors
- LookupContext should not be decoded from Thrift
- Not implemented: to_thrift for KeywordMatch
- Not implemented: to_thrift for SafetyResult
- Not implemented: to_thrift for Action
- Not implemented: to_thrift for DropReason
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/0248038bd346b696.
Report an issue: GitHub.