apache/beam · error · IllegalArgumentException
input should be array, map, numeric or row
Error message
input should be array, map, numeric or row
What it means
Cast.castValue's switch handles ARRAY, MAP, ROW, and numeric input types; any other input type (e.g. STRING, BOOLEAN, DATETIME, primitive wrappers outside numeric) falls to the default and throws IllegalArgumentException because the default cast logic does not support it.
Source
Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/transforms/Cast.java:443
Object outputKey =
castValue(entry.getKey(), input.getMapKeyType(), output.getMapKeyType());
Object outputValue =
castValue(entry.getValue(), input.getMapValueType(), output.getMapValueType());
outputMap.put(outputKey, outputValue);
}
return outputMap;
default:
if (inputType.equals(outputType)) {
return inputValue;
}
if (inputType.isNumericType()) {
return castNumber((Number) inputValue, inputType, outputType);
} else {
throw new IllegalArgumentException("input should be array, map, numeric or row");
}
}
}
}
View on GitHub (pinned to 12126d8942)
Solutions
- Handle non-numeric scalar fields with an explicit Map/MapElements transform instead of Cast.
- Write a custom cast function: rows.apply(Cast.to(schema).withCastFunction(...)) or castRow with per-field functions.
- Check which fields are non-numeric scalars via input.getSchema() and either drop or transform them before casting.
- Upgrade Beam: support for more scalar types in castValue may have been added in later versions.
Example fix
// before (STRING field hits default branch)
rows.apply(Cast.to(outSchema));
// after: transform string field explicitly first
rows.apply(MapElements.into(TypeDescriptor.of(Row.class))
.via(r -> convertStringFields(r))).apply(Cast.to(outSchema)); Defensive patterns
Strategy: validation
Validate before calling
for (Schema.Field f : inSchema.getFields()) {
TypeName t = f.getType().getTypeName();
boolean supported = EnumSet.of(TypeName.ARRAY, TypeName.MAP, TypeName.ROW).contains(t) || t.isNumericType();
if (!supported) throw new IllegalStateException("field not castable: " + f.getName());
} Type guard
static boolean castableByDefault(Schema.Field f) {
TypeName t = f.getType().getTypeName();
return t == TypeName.ARRAY || t == TypeName.MAP || t == TypeName.ROW || t.isNumericType();
} Try / catch
try { rows.apply(Cast.to(outSchema)); } catch (IllegalArgumentException e) { if (e.getMessage().contains("array, map, numeric or row")) { /* route field through MapElements */ } else throw e; } Prevention
- Inventory scalar non-numeric fields (STRING, BOOLEAN, DATETIME) before casting
- Use withCastFunction for schemas containing such fields
- Add a schema pre-flight check in pipeline construction tests
When it happens
Trigger: Applying Cast.to(outputSchema) when a field has a scalar non-numeric input type such as STRING or BOOLEAN that the switch cannot dispatch on, even if the output type matches.
Common situations: Casting schemas containing string/boolean/datetime fields; users expecting Cast to be an arbitrary value converter when it only handles structural types and numbers.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cast isn't compatible using +validator()+: +reason
- Can't cast non-numeric types: +input
- Can't cast numbers to non-numeric type: +output
- ${fieldType}
- Field type%s %s not supported when converting between JSON a
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/52246901408b4ff4.
Report an issue: GitHub.