{
  "id": "data/protobuf-oneof-unknown-field",
  "signature": "Protobuf deserialization silently drops unknown oneof fields causing data loss",
  "signature_zh": "Protobuf 反序列化静默丢弃未知的 oneof 字段导致数据丢失",
  "regex": "(?i)(protobuf.*oneof.*unknown|oneof.*silent.*drop|protobuf.*data loss.*oneof)",
  "domain": "data",
  "category": "protocol_error",
  "subcategory": null,
  "root_cause": "When a Protobuf message with a oneof field is deserialized by an older version that doesn't know the new oneof variant, the entire oneof is set to None, losing all other known fields in that oneof.",
  "root_cause_type": "generic",
  "root_cause_zh": "当包含 oneof 字段的 Protobuf 消息被不知道新 oneof 变体的旧版本反序列化时，整个 oneof 被设置为 None，丢失该 oneof 中所有其他已知字段。",
  "versions": [
    {
      "version": "Protocol Buffers 3.21.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "gRPC 1.58.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "Adding a new field outside the oneof to carry the new variant",
      "why_fails": "This changes the message structure and may cause confusion, and the oneof still gets cleared on unknown variants.",
      "fail_rate": 0.5,
      "condition": "",
      "sources": []
    },
    {
      "action": "Using 'optional' keyword for oneof fields",
      "why_fails": "The 'optional' keyword does not prevent the oneof from being cleared when an unknown variant is encountered.",
      "fail_rate": 0.7,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "Add a catch-all 'bytes unknown_oneof' field to the message to preserve raw bytes of unknown oneof variants, then manually parse.",
      "success_rate": 0.85,
      "how": "Add a catch-all 'bytes unknown_oneof' field to the message to preserve raw bytes of unknown oneof variants, then manually parse.",
      "condition": "",
      "sources": []
    },
    {
      "action": "Ensure all consumers are updated to the latest proto definition before deploying new oneof variants.",
      "success_rate": 0.9,
      "how": "Ensure all consumers are updated to the latest proto definition before deploying new oneof variants.",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "Add a catch-all 'bytes unknown_oneof' field to the message to preserve raw bytes of unknown oneof variants, then manually parse.",
    "Ensure all consumers are updated to the latest proto definition before deploying new oneof variants."
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://protobuf.dev/programming-guides/proto3/#oneof",
  "official_doc_section": null,
  "error_code": "No explicit error; silent data corruption",
  "verification_tier": "ai_generated",
  "confidence": 0.83,
  "fix_success_rate": 0.8,
  "resolvable": "partial",
  "first_seen": "2023-11-30",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}