apache/beam · error · ValueError

Expected a subclass of proto.Message, but got a %s

Error message

Expected a subclass of proto.Message, but got a %s

What it means

ProtoPlusCoder wraps proto-plus (new-style) protobuf messages. from_type_hint requires the typehint to be a subclass of proto.Message; classic google.protobuf.message.Message subclasses or arbitrary classes raise ValueError.

Source

Thrown at sdks/python/apache_beam/coders/coders.py:1252

    return coder_impl.ProtoPlusCoderImpl(self.proto_plus_message_type)

  def is_deterministic(self):
    return True

  def __eq__(self, other):
    return (
        type(self) == type(other) and
        self.proto_plus_message_type == other.proto_plus_message_type)

  def __hash__(self):
    return hash(self.proto_plus_message_type)

  @classmethod
  def from_type_hint(cls, typehint, unused_registry):
    if issubclass(typehint, proto.Message):
      return cls(typehint)
    else:
      raise ValueError(
          'Expected a subclass of proto.Message, but got a %s' % typehint)

  def to_type_hint(self):
    return self.proto_plus_message_type


AVRO_GENERIC_CODER_URN = "beam:coder:avro:generic:v1"


class AvroGenericCoder(FastCoder):
  """A coder used for AvroRecord values."""
  def __init__(self, schema):
    self.schema = schema

  def _create_impl(self):
    return coder_impl.AvroCoderImpl(self.schema)

  def is_deterministic(self):

View on GitHub (pinned to 12126d8942)

Solutions

  1. Pass a proto-plus message class (one generated/converted with the new protobuf API) to ProtoPlusCoder
  2. Use ProtoCoder (or coders.registry) for classic google.protobuf.message.Message subclasses
  3. Normalize the typehint with proto_utils helpers to pick the right coder

Example fix

// before
coder = ProtoPlusCoder.from_type_hint(school_pb2.Student, registry)
// after
coder = ProtoCoder.from_type_hint(school_pb2.Student, registry)
Defensive patterns

Strategy: type-guard

Validate before calling

import proto
is_proto_plus = isinstance(typehint, type) and issubclass(typehint, proto.Message)

Type guard

def is_proto_plus_class(t) -> bool:
    import proto
    return isinstance(t, type) and issubclass(t, proto.Message)

Try / catch

try:
    coder = ProtoPlusCoder.from_type_hint(typehint, registry)
except ValueError:
    from apache_beam.coders import ProtoCoder
    coder = ProtoCoder.from_type_hint(typehint, registry)

Prevention

When it happens

Trigger: Creating a ProtoPlusCoder via from_type_hint with a classic protobuf class or any non-proto-plus class as the typehint.

Common situations: Codebases migrating between protobuf APIs passing old generated pb2 classes where ProtoPlusCoder is expected (or vice versa); misconfigured coders in pipeline options.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/2e0e9a48191f0934. Report an issue: GitHub.