{"record":{"id":"f27db77f470bbed5","repo":"apache/beam","slug":"error-when-invoking-coder-factory-method","errorCode":null,"errorMessage":"error when invoking Coder factory method ","messagePattern":"error when invoking Coder factory method ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderProviders.java","lineNumber":79,"sourceCode":"    @Override\n    public <T> Coder<T> coderFor(TypeDescriptor<T> type, List<? extends Coder<?>> componentCoders)\n        throws CannotProvideCoderException {\n      if (!this.rawType.equals(type.getRawType())) {\n        throw new CannotProvideCoderException(\n            String.format(\n                \"Unable to provide coder for %s, this factory can only provide coders for %s\",\n                type, this.rawType));\n      }\n      try {\n        return (Coder<T>)\n            Preconditions.checkStateNotNull(\n                factoryMethod.invoke(this.rawType /* ignored */, componentCoders.toArray()));\n      } catch (IllegalAccessException\n          | IllegalArgumentException\n          | InvocationTargetException\n          | NullPointerException\n          | ExceptionInInitializerError exn) {\n        throw new IllegalStateException(\n            \"error when invoking Coder factory method \" + factoryMethod, exn);\n      }\n    }\n\n    ////////////////////////////////////////////////////////////////////////////////\n\n    // Type raw type used to filter the incoming type on.\n    private final Class<?> rawType;\n\n    // Method to create a coder given component coders\n    // For a Coder class of kind * -> * -> ... n times ... -> *\n    // this has type Coder<?> -> Coder<?> -> ... n times ... -> Coder<T>\n    private final Method factoryMethod;\n\n    /** Returns a CoderProvider that invokes the given static factory method to create the Coder. */\n    private CoderProviderFromStaticMethods(Class<?> rawType, Class<?> coderClazz) {\n      this.rawType = rawType;\n      this.factoryMethod = getFactoryMethod(coderClazz);","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderProviders.java#L61-L97","documentation":"When a CoderProvider built by CoderProviders.fromStaticMethods is asked for a coder, it reflectively invokes the Coder class's static `of` factory method. If that invocation fails for any reflective reason (inaccessible, wrong arguments, the factory itself threw, class static-initializer failure, or a null result), coderFor wraps it in this IllegalStateException. It indicates the Coder class's factory method is broken or incompatible with the component coders supplied at runtime, not a problem with the pipeline code calling coderFor.","triggerScenarios":"Calling CoderProviders.fromStaticMethods(rawType, coderClazz) and then resolving a type through CoderRegistry when the registered Coder's static of(Coder<?>...) method throws an exception internally, returns null, or the component coders passed do not match what the factory expects (e.g. wrong arity or incompatible Coder<T> generic binding due to type erasure).","commonSituations":"A custom Coder's `of` method validates component coders and throws IllegalArgumentException (caught as InvocationTargetException); a Coder was refactored so its `of` no longer accepts the registered component coders; a static initializer of the Coder class fails (ExceptionInInitializerError) from bad config or missing classes; a user-written `of` returns null on an unexpected input.","solutions":["Read the cause (exn) in the stack trace — it is the real failure from the static `of` factory method; fix the exception thrown inside your Coder's `of` method","Verify the `of` method returns a non-null Coder for all valid component-coder combinations","Check that the number and types of component coders your pipeline supplies match the type parameters of the registered Coder class","If the cause is ExceptionInInitializerError, fix the Coder class's static initializer (missing dependency, bad config)","If the Coder cannot support arbitrary component coders, register it with CoderProviders.forCoder for a concrete TypeDescriptor instead of fromStaticMethods"],"exampleFix":"// before: custom coder factory throws on unexpected component coder\npublic static MyCoder of(Coder<String> c) {\n  if (!c.getClass().equals(StringUtf8Coder.class)) { throw new IllegalArgumentException(...); }\n  ...\n}\n// after: handle any Coder<String> or throw CannotProvideCoderException path instead\npublic static MyCoder of(Coder<String> c) {\n  return new MyCoder(c); // accept any Coder<String>\n}","handlingStrategy":"try-catch","validationCode":"// verify the factory works before registering\nMethod of = coderClazz.getDeclaredMethod(\"of\",\n    java.util.Arrays.stream(coderClazz.getTypeParameters())\n        .map(p -> Coder.class).toArray(Class[]::new));\nof.setAccessible(true);\n// smoke-test with placeholder coders where feasible; of.getReturnType() must be non-void","typeGuard":"static boolean hasWorkingFactory(Class<?> coderClazz) {\n  try {\n    Class<?>[] args = new Class<?>[coderClazz.getTypeParameters().length];\n    java.util.Arrays.fill(args, Coder.class);\n    Method of = coderClazz.getDeclaredMethod(\"of\", args);\n    return Modifier.isStatic(of.getModifiers())\n        && coderClazz.isAssignableFrom(of.getReturnType()) && of.isAccessible();\n  } catch (ReflectiveOperationException | SecurityException e) { return false; }\n}","tryCatchPattern":"try {\n  Coder<T> coder = registry.getCoder(type, componentCoders);\n} catch (IllegalStateException e) {\n  // inspect e.getCause() — the failure inside the Coder's static of() method\n  logger.error(\"Coder factory failed for \" + type, e.getCause());\n  throw new CannotProvideCoderException(\"factory failure for \" + type, e);\n}","preventionTips":["Make the static of() method total: never throw or return null for valid component coders","Avoid strict instanceof checks on component coders inside of(); useCoder consolidations instead","Keep of()'s signature exactly one Coder parameter per type parameter","Smoke-test coderFor() in unit tests before registering the provider in the CoderRegistry","Read the cause chain of the IllegalStateException — it always carries the real exception from of()"],"tags":["java","reflection","coders","apache-beam"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}