{"record":{"id":"07d40bdc9a3f3c4b","repo":"apache/beam","slug":"cannot-provide-s-because-s-is-not-a-subclass-of-s-07d40b","errorCode":null,"errorMessage":"Cannot provide %s because %s is not a subclass of %s","messagePattern":"Cannot provide (.+?) because (.+?) is not a subclass of (.+?)","errorType":"exception","errorClass":"CannotProvideCoderException","httpStatus":null,"severity":"warning","filePath":"sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseMutationCoder.java","lineNumber":91,"sourceCode":"  /**\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(\n        TypeDescriptor<T> typeDescriptor, List<? extends Coder<?>> componentCoders)\n        throws CannotProvideCoderException {\n      if (!typeDescriptor.isSubtypeOf(HBASE_MUTATION_TYPE_DESCRIPTOR)) {\n        throw new CannotProvideCoderException(\n            String.format(\n                \"Cannot provide %s because %s is not a subclass of %s\",\n                HBaseMutationCoder.class.getSimpleName(),\n                typeDescriptor,\n                Mutation.class.getName()));\n      }\n\n      try {\n        @SuppressWarnings(\"unchecked\")\n        Coder<T> coder = (Coder<T>) HBaseMutationCoder.of();\n        return coder;\n      } catch (IllegalArgumentException e) {\n        throw new CannotProvideCoderException(e);\n      }\n    }\n  }\n\n  private static final TypeDescriptor<Mutation> HBASE_MUTATION_TYPE_DESCRIPTOR =","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/hbase/src/main/java/org/apache/beam/sdk/io/hbase/HBaseMutationCoder.java#L73-L109","documentation":"HBaseMutationCoderProvider is a CoderProvider that can only supply HBaseMutationCoder for types that are subtypes of Mutation. coderFor throws CannotProvideCoderException when the requested TypeDescriptor is not a Mutation subtype — this is the normal coder-resolution failure signal, not a bug.","triggerScenarios":"Beam's coder registry asks this provider for a coder for a type T; if T is not assignable to org.apache.hadoop.hbase.client.Mutation, the provider declines via CannotProvideCoderException.","commonSituations":"Pipelines whose PCollection element type resembles but isn't Mutation (e.g. RowMutations, a wrapper, or byte[]); relying on default coder inference for non-Mutation types near HBaseIO usage.","solutions":["Ensure the PCollection element type is Mutation (or a Put/Delete) when relying on the default coder.","If your type is RowMutations, HBaseRowMutationsCoder handles it — do not expect the Mutation coder to apply.","Register your own Coder explicitly for non-Mutation types instead of relying on this provider.","This exception is often expected control flow — catch it and fall back to another coder provider."],"exampleFix":"// before\np.apply(\"Read\", ...)\n .setCoder(null); // wrong coder for non-Mutation type\n// after\nPCollection<Mutation> mutations =\n    p.apply(...).setCoder(HBaseMutationCoder.of());","handlingStrategy":"type-guard","validationCode":"TypeDescriptor<?> td = TypeDescriptor.of(elementType);\nif (!td.isSubtypeOf(TypeDescriptor.of(Mutation.class))) {\n  // supply your own coder before this point\n  collection.setCoder(myExplicitCoder);\n}","typeGuard":"static <T> boolean isMutationType(TypeDescriptor<T> td) {\n  return td.isSubtypeOf(TypeDescriptor.of(Mutation.class));\n}","tryCatchPattern":"try {\n  Coder<?> c = coderRegistry.getCoder(typeDescriptor);\n} catch (CannotProvideCoderException e) {\n  // fall back to a registered/default coder or fix the element type\n  collection.setCoder(SerializableCoder.of(MyType.class));\n}","preventionTips":["Keep PCollection element types concrete (Mutation, Put, Delete) near HBaseIO stages.","Set coders explicitly with setCoder() rather than relying on registry inference.","Catch CannotProvideCoderException when doing programmatic coder lookup and fall back.","Don't confuse HBaseMutationCoder (Mutation) with HBaseRowMutationsCoder (RowMutations)."],"tags":["hbase","coder","type-system","coder-provider"],"backgroundTag":"incompatible-source-type","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"}