apache/beam · error · RuntimeException

Unexpected null element type for the map's value on " +…

Error message

Unexpected null element type for the map's value on " + field.getName()

What it means

The mirror of the key-type check: while mapping a MAP field to a repeated key/value STRUCT for BigQuery, the map's value type (getMapValueType()) is null. The converter cannot build the key/value struct fields without it, so it throws an IllegalArgumentException-style RuntimeException naming the offending field.

Solutions

  1. Construct the map field with FieldType.map(keyType, valueType) supplying a concrete value type.
  2. Pre-validate the schema: reject any MAP field with null getMapValueType() before invoking the BigQuery sink.
  3. Regenerate the schema from the actual data (e.g. via Schemainferencing) instead of reusing a damaged one.
  4. Catch the RuntimeException around schema conversion and report which field is malformed.

Example fix

// before
FieldType bad = FieldType.builder().setType(TypeName.MAP).setMapKeyType(FieldType.string()).build();
// after
FieldType ok = FieldType.map(FieldType.string(), FieldType.string());
Defensive patterns

Strategy: validation

Validate before calling

schema.getFields().stream()
  .filter(f -> f.getType().getTypeName() == Schema.TypeName.MAP)
  .forEach(f -> {
    if (f.getType().getMapValueType() == null)
      throw new IllegalArgumentException("Map field " + f.getName() + " missing value type");
  });

Type guard

boolean hasMapValueType(Schema.Field f) {
  return f.getType().getTypeName() != Schema.TypeName.MAP || f.getType().getMapValueType() != null;
}

Try / catch

try {
  protoTableSchemaFromBeamSchema(schema);
} catch (RuntimeException e) {
  if (e.getMessage().contains("null element type for the map's value")) {
    throw new SchemaException("Map field without value type: " + e.getMessage());
  }
  throw e;
}

Prevention

When it happens

Trigger: fieldDescriptorFromBeamField, case MAP, where field.getType().getMapValueType() returns null for field field.getName() - typically a FieldType of TypeName.MAP built without a value type.

Common situations: Hand-assembled or reflection-derived Beam schemas missing the value type; custom sources producing partial map FieldTypes; schema evolution tools dropping map value metadata.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BeamRowToStorageApiProto.java:280

          type = TableFieldSchema.Type.TIMESTAMP;
          builder.setTimestampPrecision(Int64Value.newBuilder().setValue(12L).build());
        } else {
          type = LOGICAL_TYPES.get(logicalType.getIdentifier());
          if (type == null) {
            throw new RuntimeException("Unsupported logical type " + field.getType());
          }
        }
        builder = builder.setType(type);
        break;
      case MAP:
        @Nullable FieldType keyType = field.getType().getMapKeyType();
        @Nullable FieldType valueType = field.getType().getMapValueType();
        if (keyType == null) {
          throw new RuntimeException(
              "Unexpected null element type for the map's key on " + field.getName());
        }
        if (valueType == null) {
          throw new RuntimeException(
              "Unexpected null element type for the map's value on " + field.getName());
        }

        builder =
            builder
                .setType(TableFieldSchema.Type.STRUCT)
                .addFields(fieldDescriptorFromBeamField(Field.of("key", keyType)))
                .addFields(fieldDescriptorFromBeamField(Field.of("value", valueType)))
                .setMode(TableFieldSchema.Mode.REPEATED);
        break;
      default:
        @Nullable
        TableFieldSchema.Type primitiveType = PRIMITIVE_TYPES.get(field.getType().getTypeName());
        if (primitiveType == null) {
          throw new RuntimeException("Unsupported type " + field.getType());
        }
        builder = builder.setType(primitiveType);
    }

View on GitHub (pinned to 12126d8942)