{"record":{"id":"d0fc12b13e9bb066","repo":"apache/beam","slug":"only-put-and-delete-are-supported","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/HBaseMutationCoder.java","lineNumber":69,"sourceCode":"  public void encode(Mutation mutation, OutputStream outStream) throws IOException {\n    MutationType type = getType(mutation);\n    MutationProto proto = ProtobufUtil.toMutation(type, mutation);\n    proto.writeDelimitedTo(outStream);\n  }\n\n  @Override\n  public Mutation decode(InputStream inStream) throws IOException {\n    return ProtobufUtil.toMutation(MutationProto.parseDelimitedFrom(inStream));\n  }\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      // Increment and Append are not idempotent.  They should not be used in distributed jobs.\n      throw new IllegalArgumentException(\"Only Put and Delete are supported\");\n    }\n  }\n\n  /**\n   * Returns a {@link CoderProvider} which uses the {@link HBaseMutationCoder} for {@link Mutation\n   * mutations}.\n   */\n  static CoderProvider getCoderProvider() {\n    return HBASE_MUTATION_CODER_PROVIDER;\n  }\n\n  private static final CoderProvider HBASE_MUTATION_CODER_PROVIDER =\n      new HBaseMutationCoderProvider();\n\n  /** A {@link CoderProvider} for {@link Mutation mutations}. */\n  private static class HBaseMutationCoderProvider extends CoderProvider {\n    @Override\n    public <T> Coder<T> coderFor(","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseMutationCoder.java#L51-L87","documentation":"HBaseMutationCoder only supports idempotent mutation types: Put and Delete. Increment and Append are non-idempotent and unsafe for distributed retries, so the coder's getType method throws IllegalArgumentException for any other Mutation subclass.","triggerScenarios":"Encoding/decoding or coder lookup for a Mutation that is an Increment or Append (or any custom Mutation subclass) inside a pipeline using HBaseMutationCoder — typically writing such mutations with HBaseIO or passing them through Coders.defaultCoder resolution.","commonSituations":"Using Increment/Append operations in a Beam HBaseIO pipeline; a custom Mutation subclass; library version change introducing new Mutation types.","solutions":["Replace Increment/Append with Put operations (compute the new value client-side) to keep idempotency.","If Delete/Put only logic is required, filter mutations before writing: only pass instanceof Put or Delete.","Use a different sink or a custom coder path if you genuinely need Increment/Append semantics."],"exampleFix":"// before\nlist.add(new Increment(row, CF, QUAL, 1L));\n// after — read current value, then Put\nlong v = readCurrentValue(row, CF, QUAL);\nlist.add(new Put(row).addColumn(CF, QUAL, Bytes.toBytes(v + 1)));","handlingStrategy":"type-guard","validationCode":"public static List<Mutation> onlyIdempotent(List<Mutation> mutations) {\n  return mutations.stream()\n      .filter(m -> m instanceof Put || m instanceof Delete)\n      .collect(Collectors.toList());\n}","typeGuard":"static boolean isSupported(Mutation m) {\n  return m instanceof Put || m instanceof Delete;\n}","tryCatchPattern":"try {\n  encodeMutation(mutation);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Only Put and Delete\")) {\n    throw new IllegalStateException(\"Replace Increment/Append with idempotent Put\", e);\n  }\n  throw e;\n}","preventionTips":["Never put Increment or Append into Beam PCollections meant for HBaseIO.","Compute values client-side and express updates as Put.","Add an upstream filter/validation step asserting Put/Delete only.","Document the idempotency requirement for your pipeline authors."],"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"}