{"record":{"id":"5375f62849895a54","repo":"apache/beam","slug":"cannot-provide-s-because-s-is-not-a-subclass-of-s","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/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/DynamicProtoCoder.java","lineNumber":185,"sourceCode":"   * proto messages}.\n   *\n   * <p>This method is invoked reflectively from {@link DefaultCoder}.\n   */\n  public static CoderProvider getCoderProvider() {\n    return new ProtoCoderProvider();\n  }\n\n  static final TypeDescriptor<Message> MESSAGE_TYPE = new TypeDescriptor<Message>() {};\n\n  /** A {@link CoderProvider} for {@link Message proto messages}. */\n  private static class ProtoCoderProvider extends CoderProvider {\n\n    @Override\n    public <T> Coder<T> coderFor(\n        TypeDescriptor<T> typeDescriptor, List<? extends Coder<?>> componentCoders)\n        throws CannotProvideCoderException {\n      if (!typeDescriptor.isSubtypeOf(MESSAGE_TYPE)) {\n        throw new CannotProvideCoderException(\n            String.format(\n                \"Cannot provide %s because %s is not a subclass of %s\",\n                DynamicProtoCoder.class.getSimpleName(), typeDescriptor, Message.class.getName()));\n      }\n\n      @SuppressWarnings(\"unchecked\")\n      TypeDescriptor<? extends Message> messageType =\n          (TypeDescriptor<? extends Message>) typeDescriptor;\n      try {\n        @SuppressWarnings(\"unchecked\")\n        Coder<T> coder = (Coder<T>) DynamicProtoCoder.of(messageType);\n        return coder;\n      } catch (IllegalArgumentException e) {\n        throw new CannotProvideCoderException(e);\n      }\n    }\n  }\n}","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/protobuf/src/main/java/org/apache/beam/sdk/extensions/protobuf/DynamicProtoCoder.java#L167-L203","documentation":"DynamicProtoCoder.coderFor() is a CoderProvider consulted by Beam's coder inference. It only supports types assignable to com.google.protobuf.Message; for any other TypeDescriptor it throws CannotProvideCoderException stating that DynamicProtoCoder cannot provide a coder because the type is not a Message subclass. This is normal provider-decline behavior, but if it is the last applicable provider, coder inference fails for the pipeline.","triggerScenarios":"Coder inference requests a coder for a type T where T is not a subclass of protobuf Message and DynamicProtoCoder.provider() is registered — e.g. a POJO, String, or custom class passed where a proto type is expected.","commonSituations":"Registering DynamicProtoCoder.provider() globally and then using non-proto types in the same pipeline (harmless unless no other provider matches); accidentally applying a proto coder to a non-proto type after a refactor; mixing generated proto classes with non-Message wrappers.","solutions":["Ensure the type in question actually extends com.google.protobuf.Message (use generated proto classes).","Register the appropriate coder for non-proto types (AvroCoder, SerializableCoder, or a custom CoderProvider).","If the type wraps a Message, make it a Message subclass or code the wrapper yourself.","Use ProtoCoder/ProtoMessageCoder directly for proto types instead of relying on dynamic inference."],"exampleFix":"// before\nPCollection<MyPojo> p = ...; // MyPojo is not a Message; inference fails\n// after\np.setCoder(AvroCoder.of(MyPojo.class));","handlingStrategy":"type-guard","validationCode":"// before requesting a coder for T\ntypeDescriptor.getRuntimeType().getTypeName(); // confirm it is the generated Message class\nboolean ok = com.google.protobuf.Message.class.isAssignableFrom(rawType);","typeGuard":"static <T> boolean isProtoMessage(TypeDescriptor<T> td) {\n  return td.isSubtypeOf(new TypeDescriptor<com.google.protobuf.Message>() {});\n}","tryCatchPattern":"try {\n  registry.getCoder(typeDescriptor);\n} catch (CannotProvideCoderException e) {\n  // fall back to a non-proto coder for non-Message types\n  coder = SerializableCoder.of(rawClass);\n}","preventionTips":["Only use DynamicProtoCoder for generated protobuf Message types","Register dedicated coders for POJOs and other non-proto types","Prefer ProtoCoder.of(MessageClass.class) for explicit proto coding"],"tags":["apache-beam","protobuf","coder","type-mismatch"],"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"}