{"record":{"id":"47532e73fdf276bc","repo":"apache/beam","slug":"cannot-encode-a-null-bytestring","errorCode":null,"errorMessage":"cannot encode a null ByteString","messagePattern":"cannot encode a null ByteString","errorType":"exception","errorClass":"CoderException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/ByteStringCoder.java","lineNumber":61,"sourceCode":"\n  /** ************************ */\n  private static final ByteStringCoder INSTANCE = new ByteStringCoder();\n\n  private static final TypeDescriptor<ByteString> TYPE_DESCRIPTOR =\n      new TypeDescriptor<ByteString>() {};\n\n  private ByteStringCoder() {}\n\n  @Override\n  public void encode(ByteString value, OutputStream outStream) throws IOException, CoderException {\n    encode(value, outStream, Context.NESTED);\n  }\n\n  @Override\n  public void encode(ByteString value, OutputStream outStream, Context context)\n      throws IOException, CoderException {\n    if (value == null) {\n      throw new CoderException(\"cannot encode a null ByteString\");\n    }\n\n    if (!context.isWholeStream) {\n      // ByteString is not delimited, so write its size before its contents.\n      VarInt.encode(value.size(), outStream);\n    }\n    value.writeTo(outStream);\n  }\n\n  @Override\n  public ByteString decode(InputStream inStream) throws IOException {\n    return decode(inStream, Context.NESTED);\n  }\n\n  @Override\n  public ByteString decode(InputStream inStream, Context context) throws IOException {\n    if (context.isWholeStream) {\n      return ByteString.readFrom(inStream);","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/ByteStringCoder.java#L43-L79","documentation":"ByteStringCoder.encode() rejects null values because a Coder in Beam must produce bytes for every element and nulls have no defined encoding. Throwing CoderException early surfaces the problem at encode time instead of writing ambiguous bytes. Nulls are not representable in Beam PCollections for coded types.","triggerScenarios":"A PCollection<ByteString> contains a null element and the element is encoded (e.g. written to a sink or shuffled); typically produced by a DoFn that emits null, or an I/O source producing null values.","commonSituations":"ParDo returning null instead of skipping; joins producing null for absent keys then feeding a protobuf/ByteString coder; GroupByKey on KV<ByteString, ...> where a null ByteString was emitted.","solutions":["Filter nulls before the coder sees them: apply Filter.by(v -> v != null).","Replace null emission with ByteString.EMPTY in the producing DoFn.","Wrap in an Optional-like type or a nullable wrapper if null is meaningful, with a coder that handles the wrapper.","Log/fix the upstream source that produced the null element."],"exampleFix":"// before\ncontext.output(value == null ? null : value.toStringUtf8().length() > 0 ? value : null);\n// after\nif (value != null) {\n  c.output(value);\n}","handlingStrategy":"type-guard","validationCode":"// before writing/encoding\nif (elements.apply(Filter.by(v -> v == null)).getCount().read() > 0) {\n  throw new IllegalStateException(\"null ByteStrings present; filter or replace with ByteString.EMPTY\");\n}","typeGuard":"static boolean isEncodable(ByteString v) { return v != null; }","tryCatchPattern":"try {\n  coder.encode(value, out, context);\n} catch (CoderException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"null ByteString\")) {\n    coder.encode(ByteString.EMPTY, out, context); // or skip element\n  } else { throw e; }\n}","preventionTips":["Never emit null from DoFns producing ByteString elements","Filter nulls immediately after sources and joins","Substitute ByteString.EMPTY for absent values"],"tags":["apache-beam","protobuf","coder","null"],"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"}