{"record":{"id":"a0588aa64b2d8f80","repo":"apache/beam","slug":"eof-encountered-decoding-a-valuekind","errorCode":null,"errorMessage":"EOF encountered decoding a ValueKind","messagePattern":"EOF encountered decoding a ValueKind","errorType":"exception","errorClass":"CoderException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/coders/ValueKindCoder.java","lineNumber":59,"sourceCode":"  private static final ValueKindCoder INSTANCE = new ValueKindCoder();\n  private static final TypeDescriptor<ValueKind> TYPE_DESCRIPTOR =\n      TypeDescriptor.of(ValueKind.class);\n\n  private ValueKindCoder() {}\n\n  @Override\n  public void encode(ValueKind value, OutputStream outStream) throws IOException, CoderException {\n    if (value == null) {\n      throw new CoderException(\"cannot encode a null ValueKind\");\n    }\n    outStream.write(ValueKindUtil.toProto(value).getNumber());\n  }\n\n  @Override\n  public ValueKind decode(InputStream inStream) throws IOException, CoderException {\n    int number = inStream.read();\n    if (number == -1) {\n      throw new CoderException(new EOFException(\"EOF encountered decoding a ValueKind\"));\n    }\n    Elements.ValueKind.@Nullable Enum proto = Elements.ValueKind.Enum.forNumber(number);\n    if (proto == null) {\n      throw new CoderException(\"Unknown ValueKind number: \" + number);\n    }\n\n    return ValueKindUtil.fromProto(proto);\n  }\n\n  @Override\n  public boolean consistentWithEquals() {\n    return true;\n  }\n\n  @Override\n  public boolean isRegisterByteSizeObserverCheap(ValueKind value) {\n    return true;\n  }","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/ValueKindCoder.java#L41-L77","documentation":"ValueKindCoder.decode reads a single byte; -1 means the stream has ended with no ValueKind to read. The coder wraps the EOFException in a CoderException so callers can distinguish premature stream end from corrupt data. This indicates truncation or decoding past the last element.","triggerScenarios":"Reading an empty stream with decode; a stream written with fewer ValueKind bytes than decode attempts; off-by-one in element counts consuming one byte too many; truncated network/file transport of runner metadata.","commonSituations":"Truncated gRPC/Dataflow harness payloads; custom runner serialization with mismatched buffer counts; replaying partial log/state files cut off mid-record.","solutions":["Verify writer and reader element counts match (one ValueKind byte per element).","Check transport integrity — compare expected byte counts to detect truncation.","Fix off-by-one loops that call decode more times than encode.","Catch CoderException with an EOFException cause and treat it as end-of-stream or a truncation error."],"exampleFix":"// before\nValueKind k = kindCoder.decode(in);\n// after\ntry {\n  ValueKind k = kindCoder.decode(in);\n} catch (CoderException e) {\n  if (e.getCause() instanceof EOFException) {\n    return; // clean end of stream, or flag truncation\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"// Confirm the stream still has at least one byte before decoding\nin.mark(1);\nboolean empty = in.read() == -1;\nin.reset();\nif (empty) throw new EOFException(\"No ValueKind byte available\");","typeGuard":"static boolean hasMoreBytes(InputStream in) throws IOException {\n  return in.available() > 0;\n}","tryCatchPattern":"try {\n  ValueKind k = kindCoder.decode(in);\n} catch (CoderException e) {\n  if (e.getCause() instanceof EOFException) {\n    return; // clean end of stream, or flag truncation\n  }\n  throw e;\n}","preventionTips":["Keep writer/reader element counts symmetric.","Compare expected vs actual byte counts on transport to catch truncation.","Avoid decode loops without an end-of-stream check.","Handle empty streams explicitly before decoding."],"tags":["java","beam","coder","eof","deserialization"],"backgroundTag":"unexpected-response-shape","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}