{"record":{"id":"e9b45c76335fb98f","repo":"apache/beam","slug":"cannot-encode-a-null-tagged-union","errorCode":null,"errorMessage":"cannot encode a null tagged union","messagePattern":"cannot encode a null tagged union","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/join/UnionCoder.java","lineNumber":48,"sourceCode":"\n/** A UnionCoder encodes RawUnionValues. */\n@SuppressWarnings({\n  \"nullness\" // TODO(https://github.com/apache/beam/issues/20497)\n})\npublic class UnionCoder extends StructuredCoder<RawUnionValue> {\n  // TODO: Think about how to integrate this with a schema object (i.e.\n  // a tuple of tuple tags).\n  /**\n   * Builds a union coder with the given list of element coders. This list corresponds to a mapping\n   * of union tag to Coder. Union tags start at 0.\n   */\n  public static UnionCoder of(List<Coder<?>> elementCoders) {\n    return new UnionCoder(elementCoders);\n  }\n\n  private int getIndexForEncoding(RawUnionValue union) {\n    if (union == null) {\n      throw new IllegalArgumentException(\"cannot encode a null tagged union\");\n    }\n    int index = union.getUnionTag();\n    if (index < 0 || index >= elementCoders.size()) {\n      throw new IllegalArgumentException(\n          \"union value index \" + index + \" not in range [0..\" + (elementCoders.size() - 1) + \"]\");\n    }\n    return index;\n  }\n\n  @Override\n  public void encode(RawUnionValue union, OutputStream outStream)\n      throws IOException, CoderException {\n    encode(union, outStream, Context.NESTED);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  @Override\n  public void encode(RawUnionValue union, OutputStream outStream, Context context)","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/join/UnionCoder.java#L30-L66","documentation":"UnionCoder encodes a tagged union value by resolving which element coder to use via the union tag. This error is thrown when encode() is called with a null RawUnionValue, because there is no tag to dispatch on and no defined encoding for null.","triggerScenarios":"Calling UnionCoder.encode (via getIndexForEncoding, invoked from index()) with a null RawUnionValue, e.g. encoding a null element inside a CoGroupByKey/TaggedKV stream.","commonSituations":"A PCollection feeding a CoGroupByKey contains null elements; user code emits null from a DoFn into a union-typed collection; a runner passes a null value during serialization.","solutions":["Filter or map out null RawUnionValues before the coder is used (e.g. drop nulls in a preceding ParDo).","Emit an empty/default union member instead of null, using a reserved union tag.","If nulls must be representable, wrap the coder in NullableCoder.of(unionCoder)."],"exampleFix":"// before\nunionCoder.encode(null, out);\n// after\nif (value != null) {\n  unionCoder.encode(value, out);\n} else {\n  NullableCoder.of(unionCoder).encode(null, out);\n}","handlingStrategy":"validation","validationCode":"if (value == null) {\n  throw new IllegalArgumentException(\"refusing to encode null union value\");\n}\nunionCoder.encode(value, outStream);","typeGuard":"boolean isEncodable(RawUnionValue v) { return v != null && v.getUnionTag() >= 0; }","tryCatchPattern":null,"preventionTips":["Filter null elements before CoGroupByKey or any union-coded stage.","Use NullableCoder when null values must be representable.","Emit an explicit 'empty' union tag instead of null sentinel values."],"tags":["java","apache-beam","coder","null-value","serialization"],"backgroundTag":"null-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}