apache/beam · error · TypeError
No types found for field
Error message
No types found for field %s
What it means
Raised while inferring the schema row type of a field when no usable non-None type could be computed from the union of candidate field types. Beam builds a RowTypeConstraint from schema fields; if the field's combined type hints collapse to nothing usable (e.g. all types are None), it cannot produce a final type and throws TypeError. This indicates the annotated schema types for the field are invalid or empty.
Solutions
- Add an explicit, non-None type annotation to the offending field (e.g. field: str).
- If the field is truly optional, annotate as Optional[T] with a concrete T so inference yields typehints.Optional[T].
- Remove NoneType-only entries from Unions on schema fields; keep at least one concrete type.
- Pass an explicit schema/row type via with_output_types or a user_type instead of relying on inference.
Example fix
// before
class Event:
def __init__(self, id):
self.id = None # no type info
// after
class Event:
def __init__(self, id: str):
self.id = id Defensive patterns
Strategy: type-guard
Validate before calling
import typing
for name, hint in typing.get_type_hints(MyClass).items():
assert hint is not None and hint is not type(None), f'field {name} lacks a concrete type'
assert len(typing.get_args(hint)) > 0 or hint is not type(None) Type guard
def has_concrete_hint(hint) -> bool:
import typing
return hint is not None and hint is not type(None) and (
not typing.get_origin(hint) == typing.Union or
any(a is not type(None) for a in typing.get_args(hint))) Try / catch
try:
row_type = beam.RowTypeConstraint.from_user_type(MyClass)
except TypeError as e:
if 'No types found for field' in str(e):
add_explicit_schema(MyClass)
else:
raise Prevention
- Annotate every schema field with a concrete type
- Prefer Optional[T] over bare None fields
- Run schema inference on classes in unit tests
- Pass explicit user_type schemas for complex fields
When it happens
Trigger: Calling schema inference (e.g. via core.py's schema type inference at core.py:4249) on a class/field where the merged field_types contain no non-None types and no single-type case applies — e.g. a field annotated only with None or with types that all reduce to NoneType.
Common situations: Using @beam.Row or dataclass schema inference with a field whose type hint is missing/None; passing Optional-only annotations in unsupported combinations; version changes in Beam's type inference handling of Optional/Union fields.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- A schema is required to write non-schema'd data.
- All dicts in batch must have the same keys. extra keys
- An explicit schema is required to write non-schema'd…
- Arrow map key field cannot be nullable
- Attempted to encode null for non-nullable field
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/6addf72eda8cbdf9.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/python/apache_beam/transforms/core.py:4249
row_dict = row.as_dict()
for field in first_fields:
field_types_by_field[field].add(
trivial_inference.instance_to_type(row_dict.get(field)))
# Determine the appropriate type for each field
final_fields = []
for field in first_fields:
field_types = field_types_by_field[field]
non_none_types = {t for t in field_types if t is not type(None)}
if len(non_none_types) > 1:
final_type = typehints.Union[tuple(non_none_types)]
elif len(non_none_types) == 1 and len(field_types) == 1:
final_type = non_none_types.pop()
elif len(non_none_types) == 1 and len(field_types) == 2:
final_type = typehints.Optional[non_none_types.pop()]
else:
raise TypeError("No types found for field %s", field)
final_fields.append((field, final_type))
return row_type.RowTypeConstraint.from_fields(final_fields)
def get_output_type(self):
return (
self.get_type_hints().simple_output_type(self.label) or
self.infer_output_type(None))
def expand(self, pbegin):
assert isinstance(pbegin, pvalue.PBegin)
serialized_values = [self._coder.encode(v) for v in self.values]
reshuffle = self.reshuffle
# Avoid the "redistributing" reshuffle for 0 and 1 element Creates.
# These special cases are often used in building up more complex
# transforms (e.g. Write).View on GitHub (pinned to 12126d8942)