{"record":{"id":"77765c9ba923e8c7","repo":"apache/beam","slug":"mutation-type-not-supported","errorCode":null,"errorMessage":"Mutation type not supported.","messagePattern":"Mutation type not 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":79,"sourceCode":"    listCoder.encode(value.getMutations(), outStream);\n  }\n\n  @Override\n  public RowMutations decode(InputStream inStream) throws IOException, IllegalArgumentException {\n\n    byte[] rowKey = byteArrayCoder.decode(inStream);\n    List<Mutation> mutations = listCoder.decode(inStream);\n\n    RowMutations rowMutations = new RowMutations(rowKey);\n    for (Mutation m : mutations) {\n      MutationType type = getType(m);\n\n      if (type == MutationType.PUT) {\n        rowMutations.add((Put) m);\n      } else if (type == MutationType.DELETE) {\n        rowMutations.add((Delete) m);\n      } else {\n        throw new IllegalArgumentException(\"Mutation type not supported.\");\n      }\n    }\n    return rowMutations;\n  }\n\n  @Override\n  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","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseRowMutationsCoder.java#L61-L97","documentation":"HBaseRowMutationsCoder.decode reads each Mutation's serialized type byte and reconstructs Put or Delete objects. A stored type byte that maps to neither PUT nor DELETE indicates a corrupted stream or unsupported type, and decode throws IllegalArgumentException('Mutation type not supported.').","triggerScenarios":"Decoding a RowMutations object whose inner mutation has a type byte other than PUT/DELETE — data written by a different/older coder version, corrupted input, or mutations that were Increment/Append smuggled in before serialization elsewhere.","commonSituations":"Mixing Beam versions where the coder format changed; hand-crafted or corrupted serialized data in state/test fixtures; RowMutations containing Increment/Append built through custom code paths.","solutions":["Ensure RowMutations only contain Put/Delete mutations before they are serialized (see getType enforcement).","Verify all pipeline stages and runners use a consistent Beam version so coder formats match.","Regenerate any persisted test fixtures/state encoded with an incompatible coder format.","If you need Increment/Append, restructure to Put-based updates."],"exampleFix":"// before\nRowMutations rm = new RowMutations(row);\nrm.add(new Increment(row, CF, QUAL, 1L)); // encoded as unsupported type\n// after\nrm.add(new Put(row).addColumn(CF, QUAL, Bytes.toBytes(newValue)));","handlingStrategy":"validation","validationCode":"public static void validateRowMutations(RowMutations rm) {\n  for (Mutation m : rm.getMutations()) {\n    if (!(m instanceof Put) && !(m instanceof Delete))\n      throw new IllegalArgumentException(\"unsupported mutation type in RowMutations: \" + m.getClass());\n  }\n}","typeGuard":"static boolean isDecodable(MutationType type) {\n  return type == MutationType.PUT || type == MutationType.DELETE;\n}","tryCatchPattern":"try {\n  RowMutations rm = coder.decode(inStream, context);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Mutation type not supported\")) {\n    throw new IOException(\"corrupt/incompatible RowMutations encoding; regenerate data with same Beam version\", e);\n  }\n  throw e;\n}","preventionTips":["Keep RowMutations limited to Put/Delete before they enter the pipeline.","Pin a consistent Beam version across producers and consumers of encoded data.","Regenerate serialized fixtures when upgrading Beam coder implementations.","Validate RowMutations contents at construction time, not at decode time."],"tags":["hbase","coder","decode","corrupt-data"],"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"}