apache/beam · error · RuntimeException

Can't cast non-numeric types: +input

Error message

Can't cast non-numeric types: +input

What it means

Cast.castNumber converts numeric values between numeric TypeNames. It first asserts the INPUT type name is a numeric type; if a non-numeric input type reaches castNumber, it throws a RuntimeException, indicating the dispatch in castValue mis-routed or the type metadata is wrong.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/transforms/Cast.java:336

    Row.Builder output = Row.withSchema(outputSchema);
    for (int i = 0; i < outputSchema.getFieldCount(); i++) {
      Schema.Field outputField = outputSchema.getField(i);

      int fromFieldIdx = inputSchema.indexOf(outputField.getName());
      Schema.Field inputField = inputSchema.getField(fromFieldIdx);

      Object inputValue = input.getValue(fromFieldIdx);
      Object outputValue = castValue(inputValue, inputField.getType(), outputField.getType());

      output.addValue(outputValue);
    }

    return output.build();
  }

  public static Number castNumber(Number value, TypeName input, TypeName output) {
    if (!input.isNumericType()) {
      throw new RuntimeException("Can't cast non-numeric types: " + input);
    }

    if (!output.isNumericType()) {
      throw new RuntimeException("Can't cast numbers to non-numeric type: " + output);
    }

    if (value == null) {
      return null;
    }

    if (input == output) {
      return value;
    }

    switch (output) {
      case BYTE:
        return value.byteValue();

View on GitHub (pinned to 12126d8942)

Solutions

  1. Fix the schema so the field's declared type matches its runtime value (numeric TypeTypes for Number values).
  2. Pre-convert non-numeric values (e.g. parse strings) with a Map/MapElements before Cast.
  3. Use a custom cast function via castRow with explicit per-field conversion logic instead of the default number path.
  4. If caused by a Beam version bug in type dispatch, upgrade Beam.

Example fix

// before (string field pushed through numeric cast)
rows.apply(Cast.to(numericSchema));
// after
rows.apply(MapElements.into(TypeDescriptor.of(Row.class))
    .via(r -> /* parse numericString to long */ rebuildRow(r))
    ).apply(Cast.to(numericSchema));
Defensive patterns

Strategy: type-guard

Validate before calling

if (row.getBaseValue("id") instanceof Number
    && schema.getField("id").getType().getTypeName().isNumericType()) { /* safe */ }

Type guard

static boolean isDeclaredNumeric(Row row, String field) {
  Object v = row.getValue(field);
  return v instanceof Number && row.getSchema().getField(field).getType().getTypeName().isNumericType();
}

Try / catch

try { rows.apply(Cast.to(outSchema)); } catch (RuntimeException e) { if (e.getMessage().startsWith("Can't cast non-numeric")) { /* fix schema/value mismatch */ } else throw e; }

Prevention

When it happens

Trigger: castValue dispatches a java Number value with an input TypeName whose isNumericType() is false — e.g. a Boolean/String-backed field value boxed as a comparable Number path, or schema metadata mismatch after custom type registration.

Common situations: Casting rows where a field's declared type (e.g. STRING) does not match the runtime value class; custom Schema coders or logical types that produce Number instances for non-numeric TypeNames.

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/de2b5eba13390f0a. Report an issue: GitHub.