{"record":{"id":"7430e750cb17989d","repo":"apache/beam","slug":"unable-to-infer-coder-for-output-of-parsefn-typedescriptors","errorCode":null,"errorMessage":"Unable to infer coder for output of parseFn (\" + TypeDescriptors.outputOf(getParseFn()) + \"). Specify it explicitly using withCoder().","messagePattern":"Unable to infer coder for output of parseFn \\(\" \\+ TypeDescriptors\\.outputOf\\(getParseFn\\(\\)\\) \\+ \"\\)\\. Specify it explicitly using withCoder\\(\\)\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/kudu/src/main/java/org/apache/beam/sdk/io/kudu/KuduIO.java","lineNumber":195,"sourceCode":"      abstract Builder<T> setFaultTolerent(Boolean faultTolerent);\n\n      abstract Builder<T> setParseFn(SerializableFunction<RowResult, T> parseFn);\n\n      abstract Builder<T> setCoder(Coder<T> coder);\n\n      abstract Builder<T> setKuduService(KuduService<T> kuduService);\n\n      abstract Read<T> build();\n    }\n\n    @VisibleForTesting\n    Coder<T> inferCoder(CoderRegistry coderRegistry) {\n      try {\n        return getCoder() != null\n            ? getCoder()\n            : coderRegistry.getCoder(TypeDescriptors.outputOf(getParseFn()));\n      } catch (CannotProvideCoderException e) {\n        throw new IllegalArgumentException(\n            \"Unable to infer coder for output of parseFn (\"\n                + TypeDescriptors.outputOf(getParseFn())\n                + \"). Specify it explicitly using withCoder().\",\n            e);\n      }\n    }\n\n    /** Reads from the Kudu cluster on the specified master addresses. */\n    public Read<T> withMasterAddresses(String masterAddresses) {\n      checkArgument(masterAddresses != null, \"masterAddresses cannot be null or empty\");\n      return builder().setMasterAddresses(Splitter.on(\",\").splitToList(masterAddresses)).build();\n    }\n\n    /** Reads from the specified table. */\n    public Read<T> withTable(String table) {\n      checkArgument(table != null, \"table cannot be null\");\n      return builder().setTable(table).build();\n    }","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/kudu/src/main/java/org/apache/beam/sdk/io/kudu/KuduIO.java#L177-L213","documentation":"KuduIO Read's coder() needs a Coder for the parseFn output type. If no explicit coder was set via withCoder(), it asks the CoderRegistry to infer one from the parseFn's generic output type; when inference fails (CannotProvideCoderException) it rethrows as this IllegalArgumentException.","triggerScenarios":"Building/serializing a KuduIO read whose parseFn output type is not statically inferable or has no registered default coder (e.g., a custom POJO without @DefaultSchema/registered coder, or a lambda erasing the generic type).","commonSituations":"Using a parseFn returning a custom class or a generic/lambda-typed result in KuduIO.read(), especially when the pipeline is being expanded and coders must be resolved.","solutions":["Call KuduIO.read().withCoder(MyCoder.of()) (or withCoder(CoderRegistry-wide coder)) to supply the coder explicitly","Register a default coder for the output type via CoderRegistry.registerCoderForClass or annotate the type so Beam can infer it","Use a parseFn whose output type is a well-known Beam-supported type (Row, String, etc.) so inference succeeds"],"exampleFix":"// before\nKuduIO.read().withTable(table).withParseFn(row -> new MyPojo(row));\n// after\nKuduIO.read().withTable(table).withParseFn(row -> new MyPojo(row))\n    .withCoder(SerializableCoder.of(MyPojo.class));","handlingStrategy":"try-catch","validationCode":"CoderRegistry registry = pipeline.getCoderRegistry();\ntry {\n  registry.getCoder(TypeDescriptors.outputOf(parseFn));\n} catch (CannotProvideCoderException e) {\n  // supply withCoder(...) explicitly\n}","typeGuard":null,"tryCatchPattern":"try {\n  Read<T> read = kuduIoRead;\n  // expansion resolves coder\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Unable to infer coder for output of parseFn\")) {\n    read = read.withCoder(SerializableCoder.of(MyPojo.class));\n  }\n}","preventionTips":["Always call withCoder when parseFn returns custom types","Use Beam-supported types (Row, primitive wrappers, String) as parseFn output","Register default coders for shared POJOs in the CoderRegistry at pipeline setup"],"tags":["java","apache-beam","kudu","coder-inference","generics"],"backgroundTag":"type-mismatch","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"}