apache/beam · error · IllegalArgumentException
%s requires an input Schema. Note that only Row or user clas
Error message
%s requires an input Schema. Note that only Row or user classes are supported. Consider using TextIO or FileIO directly when writing primitive types
What it means
JsonIO.Write.expand() requires the input PCollection to have a schema (via Beam's schema inference); only Row-backed or schema-annotated user classes are supported. If hasSchema() is false, it throws this IllegalArgumentException suggesting TextIO/FileIO for primitive types. JsonIO writes JSON via schema-derived serialization, so untyped PCollections cannot be handled.
Source
Thrown at sdks/java/io/json/src/main/java/org/apache/beam/sdk/io/json/JsonIO.java:267
@AutoValue.Builder
abstract static class Builder<T> {
/**
* The underlying {@link FileIO.Write} that writes converted input to JSON formatted output.
*/
abstract Builder<T> setTextIOWrite(TextIO.Write value);
abstract Write<T> autoBuild();
final Write<T> build() {
return autoBuild();
}
}
@Override
public WriteFilesResult<String> expand(PCollection<T> input) {
if (!input.hasSchema()) {
throw new IllegalArgumentException(
String.format(
"%s requires an input Schema. Note that only Row or user classes are supported. Consider using TextIO or FileIO directly when writing primitive types",
Write.class.getName()));
}
Schema schema = input.getSchema();
RowCoder rowCoder = RowCoder.of(schema);
PCollection<Row> rows =
input
.apply("To Rows", MapElements.into(rows()).via(input.getToRowFunction()))
.setCoder(rowCoder);
SerializableFunction<Row, String> toJsonFn =
JsonUtils.getRowToJsonStringsFunction(input.getSchema());
PCollection<String> json = rows.apply("To JSON", MapElements.into(strings()).via(toJsonFn));View on GitHub (pinned to 12126d8942)
Solutions
- Use TextIO.write() for PCollection<String> of raw JSON text instead of JsonIO.
- Annotate your POJO with @DefaultSchema and register it via SchemaRegistry, or convert to Row via setSchema.
- Apply a schema-providing transform (e.g. withTypeDescriptor/setRowSchema) before JsonIO.write.
Example fix
// before
pc.apply("write", JsonIO.write().to(path)); // pc is PCollection<String>
// after
pc.apply("write", TextIO.write().to(path));
// or give the PCollection a schema:
pc.setSchema(schema); pc.apply(JsonIO.write().to(path)); Defensive patterns
Strategy: type-guard
Validate before calling
if (input == null || !input.hasSchema()) {
// use TextIO.write() for raw strings, or set a schema first
} Type guard
boolean isSchemaBacked(PCollection<?> pc) {
return pc != null && pc.hasSchema();
} Try / catch
try { pc.apply(JsonIO.write().to(out)); }
catch (IllegalArgumentException e) {
if (e.getMessage().contains("requires an input Schema")) { /* switch to TextIO or add schema */ }
throw e;
} Prevention
- Only apply JsonIO.write to Row-backed or @DefaultSchema-annotated collections.
- Use TextIO for PCollection<String> of pre-serialized JSON.
- Register POJO schemas with the Beam SchemaRegistry early in pipeline setup.
When it happens
Trigger: Calling JsonIO.write() on a PCollection<String>, PCollection<Map<...>>, or other primitive/untyped collection without a registered schema or TypeDescriptor.
Common situations: Applying JsonIO.write directly to raw JSON strings read from TextIO; using POJOs without @DefaultSchema/GetSchema annotations; passing primitive types that Beam cannot infer schemas for.
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
- Non-nullable field '{name}' is not present in the JSON objec
- Non-nullable field '{name}' has value null in the JSON objec
- Value "{value}" is out of range for the type of the field de
- Unable to generate coder for schema {schema}
- Expecting exactly one field, found
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/1538e9e3af5bcb4a.
Report an issue: GitHub.