{"record":{"id":"cd23c841dd3bc56c","repo":"apache/beam","slug":"only-put-and-delete-are-supported-hbaserowmutationscoder","errorCode":null,"errorMessage":"Only Put and Delete are supported","messagePattern":"Only Put and Delete are supported","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseRowMutationsCoder.java","lineNumber":104,"sourceCode":"  public List<? extends Coder<?>> getCoderArguments() {\n    return Arrays.asList(listCoder, byteArrayCoder);\n  }\n\n  /**\n   * Coder is always deterministic: 1. {@link RowMutations} maintains equality by row key only,\n   * which is asserted equal in this coder 2. Canonical encoding is maintained regardless of object\n   * machine or time context\n   */\n  @Override\n  public void verifyDeterministic() {}\n\n  private static MutationType getType(Mutation mutation) {\n    if (mutation instanceof Put) {\n      return MutationType.PUT;\n    } else if (mutation instanceof Delete) {\n      return MutationType.DELETE;\n    } else {\n      throw new IllegalArgumentException(\"Only Put and Delete are supported\");\n    }\n  }\n\n  /**\n   * Returns a {@link CoderProvider} which uses the {@link HBaseRowMutationsCoder} for {@link\n   * RowMutations}.\n   */\n  static CoderProvider getCoderProvider() {\n    return HBASE_ROW_MUTATIONS_CODER_PROVIDER;\n  }\n\n  private static final CoderProvider HBASE_ROW_MUTATIONS_CODER_PROVIDER =\n      new HBaseRowMutationsCoderProvider();\n\n  /** A {@link CoderProvider} for {@link Mutation mutations}. */\n  private static class HBaseRowMutationsCoderProvider extends CoderProvider {\n    @Override\n    public <T> Coder<T> coderFor(","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseRowMutationsCoder.java#L86-L122","documentation":"Identical to HBaseMutationCoder's check: HBaseRowMutationsCoder.getType maps a Mutation to PUT or DELETE for serialization and throws IllegalArgumentException for anything else, because Increment/Append are non-idempotent and disallowed in distributed jobs.","triggerScenarios":"Serializing (encoding) a RowMutations whose add() received an Increment, Append, or custom Mutation subclass; coder resolution over a PCollection of RowMutations containing such mutations.","commonSituations":"Counters/atomic increments implemented with Increment inside RowMutations; custom Mutation subclasses; code that generically collects Mutation objects into RowMutations.","solutions":["Convert Increment/Append logic into Put with values computed client-side.","Filter or validate RowMutations contents before applying them to the pipeline.","Extend explicitly only with Put/Delete if you control mutation construction."],"exampleFix":"// before\nmutations.forEach(m -> rowMutations.add(m)); // may include Increment\n// after\nmutations.stream()\n    .filter(m -> m instanceof Put || m instanceof Delete)\n    .forEach(m -> rowMutations.add(m));","handlingStrategy":"type-guard","validationCode":"List<Mutation> safe = mutations.stream()\n    .peek(m -> { if (!(m instanceof Put) && !(m instanceof Delete))\n      throw new IllegalArgumentException(\"non-idempotent mutation: \" + m.getClass()); })\n    .collect(Collectors.toList());","typeGuard":"static boolean isEncodable(Mutation m) {\n  return m instanceof Put || m instanceof Delete;\n}","tryCatchPattern":"try {\n  rowMutations.add(mutation);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Only Put and Delete\")) {\n    // convert Increment to Put before adding\n    rowMutations.add(toPut(mutation));\n  } else throw e;\n}","preventionTips":["Express counter-style updates as read-then-Put instead of Increment.","Filter generic Mutation collections down to Put/Delete before building RowMutations.","Add unit tests asserting every Mutation is Put/Delete before encoding.","Avoid custom Mutation subclasses in Beam pipelines."],"tags":["hbase","coder","unsupported-mutation","idempotency"],"backgroundTag":"unsupported-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"}