{"record":{"id":"fdf1f00f8eb45caf","repo":"apache/beam","slug":"cannot-infer-coder-for-type-parameter","errorCode":null,"errorMessage":"Cannot infer coder for type parameter ","messagePattern":"Cannot infer coder for type parameter ","errorType":"exception","errorClass":"CannotProvideCoderException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderRegistry.java","lineNumber":334,"sourceCode":"   *     this functionality is refined.\n   */\n  @Deprecated\n  @Internal\n  public <T, OutputT> Coder<OutputT> getCoder(\n      Class<? extends T> subClass,\n      Class<T> baseClass,\n      Map<Type, ? extends Coder<?>> knownCoders,\n      TypeVariable<?> param)\n      throws CannotProvideCoderException {\n\n    Map<Type, Coder<?>> inferredCoders = getDefaultCoders(subClass, baseClass, knownCoders);\n\n    @SuppressWarnings(\"unchecked\")\n    Coder<OutputT> paramCoderOrNull = (Coder<OutputT>) inferredCoders.get(param);\n    if (paramCoderOrNull != null) {\n      return paramCoderOrNull;\n    } else {\n      throw new CannotProvideCoderException(\"Cannot infer coder for type parameter \" + param);\n    }\n  }\n\n  /////////////////////////////////////////////////////////////////////////////\n\n  /**\n   * Returns a {@code Map} from each of {@code baseClass}'s type parameters to the {@link Coder} to\n   * use for it, in the context of {@code subClass}'s specialization of {@code baseClass}.\n   *\n   * <p>If no {@link Coder} can be inferred for a particular type parameter, then that type variable\n   * will be absent from the returned {@code Map}.\n   *\n   * <p>For example, if {@code baseClass} is {@code Map.class}, where {@code Map<K, V>} has type\n   * parameters {@code K} and {@code V}, and {@code subClass} extends {@code Map<String, Integer>}\n   * then the result will map the type variable {@code K} to a {@code Coder<String>} and the type\n   * variable {@code V} to a {@code Coder<Integer>}.\n   *\n   * <p>The {@code knownCoders} parameter can be used to provide known {@link Coder Coders} for any","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CoderRegistry.java#L316-L352","documentation":"CoderRegistry.getParamCoder (reached via getCoder) tries to map a generic type parameter (e.g. OutputT on a DoFn's ProcessElement) to a concrete coder from previously inferred coders. When the type parameter has no matching inferred entry — usually because the subclass did not parameterize the base class with a concrete type — it throws CannotProvideCoderException 'Cannot infer coder for type parameter'.","triggerScenarios":"Using a DoFn/subclass with a bare type variable (e.g. class MyFn<T> extends DoFn<T, T>) instead of a concrete parameterization (class MyFn extends DoFn<String, String>); calling getOutputCoder/getDefaultOutputCoder on a class whose type arguments are still unresolved type variables.","commonSituations":"Anonymous subclasses or lambdas without a resolvable generic signature; helper generic classes wrapping DoFns; superclass is generic and instantiated without type args so TypeDescriptor inference yields T.","solutions":["Parameterize the subclass with concrete types, e.g. class MyFn extends DoFn<String, String> instead of raw/generic subclass","Provide the coder explicitly via .setCoder(...) or by overriding getOutputCoder/getDefaultOutputCoder","Use TypeDescriptor supplies at transform calls (e.g. apply(..., new TypeDescriptor<Map<K,V>>() {})) so inference has a concrete type","Check the call site (getOutputCoder, getAccumulatorCoder, bazCoder, fooCoder) for where the type parameter was expected to be bound"],"exampleFix":"// before\nclass MyFn<T> extends DoFn<T, T> { ... } // cannot infer coder for T\n// after\nclass MyFn extends DoFn<String, String> { ... }","handlingStrategy":"type-guard","validationCode":"Type sup = TypeDescriptor.of(subClass).getSupertype(DoFn.class).getType();\nboolean concrete = !(sup instanceof TypeVariable);","typeGuard":"boolean isGenericBound = !(TypeDescriptor.of(fn.getClass()).getSupertype(DoFn.class).getType() instanceof TypeVariable);","tryCatchPattern":"try {\n  coder = registry.getOutputCoder(fn, inputType);\n} catch (CannotProvideCoderException e) {\n  coder = defaultCoderForMyType;\n}","preventionTips":["Never subclass DoFn/CombineFn with bare type variables; always use concrete type arguments","Avoid anonymous generic classes where type args cannot be resolved; use named concrete subclasses","Override getDefaultOutputCoder when inference would be ambiguous"],"tags":["java","apache-beam","coders","generics","type-inference"],"backgroundTag":"type-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}