apache/beam · error · IllegalStateException

Field `{keyField}` should of type `BYTES`. Please change the

Error message

Field `{keyField}` should of type `BYTES`. Please change the type or specify a field to store the KEY value.

What it means

EntityToRow converts a Datastore Entity into a Beam Row. If the schema declares a field for storing the Entity KEY, that field must be of Beam type BYTES. This error is thrown from the private constructor when the chosen keyField exists in the schema but its type is anything other than BYTES, because the raw key bytes could not be stored correctly.

Source

Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/datastore/EntityToRow.java:54

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** A {@code PTransform} to perform a conversion of {@link Entity} to {@link Row}. */
@SuppressWarnings({
  "nullness" // TODO(https://github.com/apache/beam/issues/20497)
})
public class EntityToRow extends PTransform<PCollection<Entity>, PCollection<Row>> {
  private final Schema schema;
  private final String keyField;
  private static final Logger LOG = LoggerFactory.getLogger(EntityToRow.class);

  private EntityToRow(Schema schema, String keyField) {
    this.schema = schema;
    this.keyField = keyField;

    if (schema.getFieldNames().contains(keyField)) {
      if (!schema.getField(keyField).getType().getTypeName().equals(Schema.TypeName.BYTES)) {
        throw new IllegalStateException(
            "Field `"
                + keyField
                + "` should of type `BYTES`. Please change the type or specify a field to"
                + " store the KEY value.");
      }
      LOG.info("Entity KEY will be stored under `{}` field.", keyField);
    }
  }

  /**
   * Create a PTransform instance.
   *
   * @param schema {@code Schema} of the target row.
   * @param keyField A name of the row field to store the {@code Key} in.
   * @return {@code PTransform} instance for Entity to Row conversion.
   */
  public static EntityToRow create(Schema schema, String keyField) {
    return new EntityToRow(schema, keyField);

View on GitHub (pinned to 12126d8942)

Solutions

  1. Change the keyField column type in the schema to Schema.FieldType.BYTES
  2. Or pick a different (BYTES-typed) field via the keyField option, or add a new BYTES field to hold the key
  3. Regenerate the schema from your pipeline so the key field is defined as BYTES from the start

Example fix

// before
Schema schema = Schema.of(Schema.Field.of("id", Schema.FieldType.STRING));
// after
Schema schema = Schema.of(Schema.Field.of("id", Schema.FieldType.BYTES));
Defensive patterns

Strategy: validation

Validate before calling

if (schema.getFieldNames().contains(keyField)
    && !schema.getField(keyField).getType().getTypeName().equals(Schema.TypeName.BYTES)) {
  throw new IllegalArgumentException(
      "keyField `" + keyField + "` must be BYTES, got "
      + schema.getField(keyField).getType().getTypeName());
}

Type guard

boolean isValidKeyField(Schema schema, String keyField) {
  return !schema.getFieldNames().contains(keyField)
      || schema.getField(keyField).getType().getTypeName().equals(Schema.TypeName.BYTES);
}

Prevention

When it happens

Trigger: Constructing an EntityToRow via withSchema/descendant factory methods with a keyField name that exists in the schema but is declared as e.g. STRING, INT64, or ROW instead of BYTES.

Common situations: Schema imported from BigQuery/Avro where the key column was inferred as STRING; user renamed the key field but left the old column type; copy-paste of a schema where the key field was given a human-readable type.

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