{"record":{"id":"caa7db2aa8892a3e","repo":"xai-org/x-algorithm","slug":"rust-vf-filter-tweets-error-status","errorCode":null,"errorMessage":"Rust VF filter_tweets error: {status}","messagePattern":"Rust VF filter_tweets error: (.+?)","errorType":"error_code","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"visibility-filtering-client/vf_client.rs","lineNumber":342,"sourceCode":"        .map(|r| (r.tweet_id, Ok(result_to_reason(r))))\n        .collect();\n    for &tweet_id in requested_tweet_ids {\n        map.entry(tweet_id)\n            .or_insert_with(|| Ok(Some(FilteredReason::UnspecifiedReason)));\n    }\n    map\n}\n\nfn rpc_error_map(\n    tweet_ids: &[u64],\n    status: &tonic::Status,\n) -> HashMap<u64, Result<Option<FilteredReason>>> {\n    tweet_ids\n        .iter()\n        .map(|&tweet_id| {\n            (\n                tweet_id,\n                Err(anyhow!(\"Rust VF filter_tweets error: {status}\")),\n            )\n        })\n        .collect()\n}\n\nfn classify_filter_tweets_error_code(code: tonic::Code) -> &'static str {\n    match code {\n        tonic::Code::DeadlineExceeded => \"deadline_exceeded\",\n        tonic::Code::Cancelled => \"cancelled\",\n        tonic::Code::Unavailable => \"unavailable\",\n        _ => \"other\",\n    }\n}\n\n#[derive(Debug, Default, PartialEq, Eq)]\nstruct FilterTweetsClientMetrics {\n    error_codes: Vec<&'static str>,\n    failed_ids: u64,","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/visibility-filtering-client/vf_client.rs#L324-L360","documentation":"Produced by rpc_error_map, which converts a failed gRPC filter_tweets call into a HashMap where every requested tweet_id maps to Err(\"Rust VF filter_tweets error: {status}\"). It represents a whole-batch RPC failure — the VF gRPC endpoint itself errored, so no tweet could be evaluated.","triggerScenarios":"Calling get_result when the underlying tonic/gRPC filter_tweets RPC returns a non-OK status: UNAVAILABLE (VF service down), DEADLINE_EXCEEDED, UNAUTHENTICATED, PERMISSION_DENIED, or INTERNAL from the VF server.","commonSituations":"VF service outages or rolling restarts; gRPC deadline too short for large batches; missing/invalid auth metadata; envoy/sidecar issues between client and VF; RESOLUTION failures for the VF endpoint.","solutions":["Retry with backoff for transient codes (UNAVAILABLE, DEADLINE_EXCEEDED) and shrink the batch size if deadlines keep hitting","Check VF service health and the gRPC status string in the message for the specific code","Verify auth metadata/credentials attached to the VF channel","Increase the RPC deadline for large tweet_id batches"],"exampleFix":"// before\nlet results = client.filter_tweets(ids).await\n    .unwrap_or_else(|status| rpc_error_map(&ids, &status));\n\n// after\nlet results = match client.filter_tweets(ids).await {\n    Ok(r) => r,\n    Err(status) if status.code() == tonic::Code::Unavailable => {\n        tokio::time::sleep(Duration::from_millis(250)).await;\n        client.filter_tweets(ids).await\n            .unwrap_or_else(|status| rpc_error_map(&ids, &status))\n    }\n    Err(status) => rpc_error_map(&ids, &status),\n};","handlingStrategy":"retry","validationCode":"null","typeGuard":null,"tryCatchPattern":"match vf_call(ids).await { Err(status) if matches!(status.code(), tonic::Code::Unavailable | tonic::Code::DeadlineExceeded) => retry_smaller_batch(...).await, r => r.unwrap_or_else(|s| rpc_error_map(&ids, &s)) }","preventionTips":["Set gRPC deadlines proportional to batch size","Break huge batches into chunks","Circuit-break the VF dependency when UNAVAILABLE persists"],"tags":["grpc","visibility-filtering","rpc-failure","batch","rust"],"backgroundTag":"grpc-rpc-failed","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}