apache/beam · error · CoderException

cannot encode a null ValueKind

Error message

cannot encode a null ValueKind

What it means

ValueKindCoder encodes a ValueKind as its protobuf enum number (a single byte) and rejects null with CoderException, since ValueKind has no null member. A null kind indicates an uninitialized field in the surrounding machinery rather than serializable data.

Source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/coders/ValueKindCoder.java:50

 * Elements.ValueKind.Enum} number, so the wire format stays stable if the enum is reordered and
 * matches the portability representation.
 */
public class ValueKindCoder extends AtomicCoder<ValueKind> {

  public static ValueKindCoder of() {
    return INSTANCE;
  }

  private static final ValueKindCoder INSTANCE = new ValueKindCoder();
  private static final TypeDescriptor<ValueKind> TYPE_DESCRIPTOR =
      TypeDescriptor.of(ValueKind.class);

  private ValueKindCoder() {}

  @Override
  public void encode(ValueKind value, OutputStream outStream) throws IOException, CoderException {
    if (value == null) {
      throw new CoderException("cannot encode a null ValueKind");
    }
    outStream.write(ValueKindUtil.toProto(value).getNumber());
  }

  @Override
  public ValueKind decode(InputStream inStream) throws IOException, CoderException {
    int number = inStream.read();
    if (number == -1) {
      throw new CoderException(new EOFException("EOF encountered decoding a ValueKind"));
    }
    Elements.ValueKind.@Nullable Enum proto = Elements.ValueKind.Enum.forNumber(number);
    if (proto == null) {
      throw new CoderException("Unknown ValueKind number: " + number);
    }

    return ValueKindUtil.fromProto(proto);
  }

View on GitHub (pinned to 12126d8942)

Solutions

  1. Initialize the ValueKind field before encoding (e.g. ValueKind.IMMUTABLE or the appropriate constant).
  2. Default null kinds to a valid sentinel enum constant at construction time.
  3. Verify ValueKindUtil.fromProto returns non-null for every enum number you emit.
  4. Inspect the stack trace to find which builder/constructor left the kind unset.

Example fix

// before
kindCoder.encode(kind, out); // kind may be null
// after
ValueKind safeKind = kind != null ? kind : ValueKind.IMMUTABLE;
kindCoder.encode(safeKind, out);
Defensive patterns

Strategy: validation

Validate before calling

if (kind == null) {
  throw new IllegalArgumentException("ValueKind must be set before encoding");
}

Type guard

static boolean encodable(ValueKind k) { return k != null; }

Try / catch

try {
  kindCoder.encode(kind, out);
} catch (CoderException e) {
  throw new SerializationException("Unset ValueKind", e);
}

Prevention

When it happens

Trigger: Calling ValueKindCoder.encode(null, out) directly; internal structures where a ValueKind field was never initialized; proto-to-ValueKind conversion code that left the field unset before encoding.

Common situations: Runner/harness integration code building element-kind metadata; proto conversions leaving optional ValueKind fields unset; custom pipeline fragment assembly skipping the kind field.

Related errors


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