{"record":{"id":"6e73fb2b91a3aafb","repo":"apache/beam","slug":"expected-a-strict-subclass-of-google-protobuf-message","errorCode":null,"errorMessage":"Expected a strict subclass of google.protobuf.message.Message, but got a %s","messagePattern":"Expected a strict subclass of google\\.protobuf\\.message\\.Message, but got a (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/coders/coders.py","lineNumber":1196,"sourceCode":"        type(self) == type(other) and\n        self.proto_message_type == other.proto_message_type)\n\n  def __hash__(self):\n    return hash(self.proto_message_type)\n\n  @classmethod\n  def from_type_hint(cls, typehint, unused_registry):\n    # The typehint must be a strict subclass of google.protobuf.message.Message.\n    # ProtoCoder cannot work with message.Message itself, as deserialization of\n    # a serialized proto requires knowledge of the desired concrete proto\n    # subclass which is not stored in the encoded bytes themselves. If this\n    # occurs, an error is raised and the system defaults to other fallback\n    # coders.\n    if (issubclass(typehint, proto_utils.message_types) and\n        typehint != message.Message):\n      return cls(typehint)\n    else:\n      raise ValueError((\n          'Expected a strict subclass of google.protobuf.message.Message'\n          ', but got a %s' % typehint))\n\n  def to_type_hint(self):\n    return self.proto_message_type\n\n\nclass DeterministicProtoCoder(ProtoCoder):\n  \"\"\"A deterministic Coder for Google Protocol Buffers.\n\n  It supports both Protocol Buffers syntax versions 2 and 3. However,\n  the runtime version of the python protobuf library must exactly match the\n  version of the protoc compiler what was used to generate the protobuf\n  messages.\n  \"\"\"\n  def _create_impl(self):\n    return coder_impl.DeterministicProtoCoderImpl(self.proto_message_type)\n","sourceCodeStart":1178,"sourceCodeEnd":1214,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/coders/coders.py#L1178-L1214","documentation":"ProtoCoder only accepts classic google.protobuf Message subclasses (not proto-plus wrappers). from_type_hint validates that the typehint is a strict subclass of google.protobuf.message.Message; anything else (including Message itself or a proto-plus type) raises ValueError.","triggerScenarios":"Creating a ProtoCoder via from_type_hint with a typehint that is google.protobuf.message.Message itself, a proto-plus message class, or a non-protobuf class.","commonSituations":"Mixing proto-plus (new protobuf API) types with ProtoCoder; annotating a DoFn with a base Message class instead of the concrete generated class; pipeline type inference handing the wrong typehint.","solutions":["Use the concrete generated protobuf class (e.g. my_pb2.MyMessage) as the typehint","If your messages use proto-plus, use ProtoPlusCoder instead of ProtoCoder","Verify with proto_utils.is_message_type(typehint) before constructing"],"exampleFix":"// before\ncoder = ProtoCoder.from_type_hint(message.Message, registry)\n// after\ncoder = ProtoCoder.from_type_hint(school_pb2.Student, registry)","handlingStrategy":"type-guard","validationCode":"from google.protobuf import message\nfrom apache_beam.utils import proto_utils\ncan_use = isinstance(typehint, type) and issubclass(typehint, message.Message) and typehint is not message.Message","typeGuard":"def is_classic_proto_class(t) -> bool:\n    from google.protobuf import message\n    return isinstance(t, type) and issubclass(t, message.Message) and t is not message.Message","tryCatchPattern":"try:\n    coder = ProtoCoder.from_type_hint(typehint, registry)\nexcept ValueError:\n    coder = ProtoPlusCoder.from_type_hint(typehint, registry)","preventionTips":["Annotate pipelines with concrete generated pb2 classes, not message.Message","Use ProtoPlusCoder for proto-plus types, ProtoCoder for classic ones","Check the coder registry picks the right proto coder automatically"],"tags":["python","protobuf","coders","apache-beam"],"backgroundTag":"incompatible-source-type","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}