{"record":{"id":"a0376bea14dea00d","repo":"apache/beam","slug":"unknown-endkeycase","errorCode":null,"errorMessage":"Unknown endKeyCase: ","messagePattern":"Unknown endKeyCase: ","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableServiceImpl.java","lineNumber":789,"sourceCode":"    private final ByteString value;\n    private final boolean isClosed;\n\n    @NonNull\n    static EndPoint extract(@NonNull RowRange rowRange) {\n      switch (rowRange.getEndKeyCase()) {\n        case ENDKEY_NOT_SET:\n          return new EndPoint(ByteString.EMPTY, true);\n        case END_KEY_CLOSED:\n          return new EndPoint(rowRange.getEndKeyClosed(), true);\n        case END_KEY_OPEN:\n          if (rowRange.getEndKeyOpen().isEmpty()) {\n            // Take care to normalize an open empty end key to be closed.\n            return new EndPoint(ByteString.EMPTY, true);\n          } else {\n            return new EndPoint(rowRange.getEndKeyOpen(), false);\n          }\n        default:\n          throw new IllegalArgumentException(\"Unknown endKeyCase: \" + rowRange.getEndKeyCase());\n      }\n    }\n\n    private EndPoint(@NonNull ByteString value, boolean isClosed) {\n      this.value = value;\n      this.isClosed = isClosed;\n    }\n\n    @Override\n    public int compareTo(@NonNull EndPoint o) {\n      return ComparisonChain.start()\n          // Empty string comes last\n          .compareFalseFirst(value.isEmpty(), o.value.isEmpty())\n          .compare(value, o.value, ByteStringComparator.INSTANCE)\n          // Open end point comes before a closed end point: [x,y) ends before [x,y].\n          .compareFalseFirst(isClosed, o.isClosed)\n          .result();\n    }","sourceCodeStart":771,"sourceCodeEnd":807,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigtable/BigtableServiceImpl.java#L771-L807","documentation":"When converting a RowRange's end key into an internal EndPoint, BigtableServiceImpl switches over the protobuf endKeyCase. If the case is none of END_KEY_CLOSED, END_KEY_OPEN, an IllegalArgumentException with 'Unknown endKeyCase: ' is thrown.","triggerScenarios":"Passing a RowRange whose end key is unset (neither setEndKeyClosed nor setEndKeyOpen called) to BigtableIO.withKeyRange, or a range whose proto oneof is in an unrecognized state.","commonSituations":"Building ranges dynamically where the end key computation failed silently and left the field unset; hand-crafted protos copied from different table configs.","solutions":["Set either setEndKeyClosed or setEndKeyOpen on the RowRange before use","Use RowRange.newBuilder().setEndKeyOpen(ByteString.EMPTY) to scan through the end of the table","Validate ranges in the code that constructs them before handing them to the Beam source"],"exampleFix":"// before\nRowRange range = RowRange.newBuilder().setStartKeyClosed(start).build(); // no end key\n// after\nRowRange range = RowRange.newBuilder()\n    .setStartKeyClosed(start)\n    .setEndKeyOpen(ByteString.EMPTY)\n    .build();","handlingStrategy":"validation","validationCode":"boolean hasEndKey(RowRange r) {\n  return r.getEndKeyCase() != RowRange.EndKeyCase.ENDKEY_NOT_SET;\n}","typeGuard":"boolean endKeySet(RowRange range) {\n  return range.getEndKeyCase() == RowRange.EndKeyCase.END_KEY_CLOSED\n      || range.getEndKeyCase() == RowRange.EndKeyCase.END_KEY_OPEN;\n}","tryCatchPattern":null,"preventionTips":["Always call setEndKeyClosed/setEndKeyOpen when constructing ranges","Use setEndKeyOpen(ByteString.EMPTY) for an unbounded end","Validate ranges centrally before passing them to BigtableIO.withKeyRange"],"tags":["gcp","bigtable","argument","range"],"backgroundTag":"invalid-enum-value","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"}