{"record":{"id":"62a5c9efb8952c93","repo":"apache/beam","slug":"unable-to-infer-a-coder-for-destination-type-inferred-from","errorCode":null,"errorMessage":"Unable to infer a coder for destination type (inferred from .by() as \\\"\" + destinationT + \"\\\") - specify it explicitly using .withDestinationCoder()","messagePattern":"Unable to infer a coder for destination type \\(inferred from \\.by\\(\\) as \\\\\"\" \\+ destinationT \\+ \"\\\\\"\\) - specify it explicitly using \\.withDestinationCoder\\(\\)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileIO.java","lineNumber":1564,"sourceCode":"      }\n      if (getBatchSizeBytes() != null) {\n        writeFiles = writeFiles.withBatchSizeBytes(getBatchSizeBytes());\n      }\n      if (getBatchMaxBufferingDuration() != null) {\n        writeFiles = writeFiles.withBatchMaxBufferingDuration(getBatchMaxBufferingDuration());\n      }\n      return input.apply(writeFiles);\n    }\n\n    private Coder<DestinationT> resolveDestinationCoder(PCollection<UserT> input) {\n      Coder<DestinationT> destinationCoder = getDestinationCoder();\n      if (destinationCoder == null) {\n        TypeDescriptor<DestinationT> destinationT =\n            TypeDescriptors.outputOf(getDestinationFn().getClosure());\n        try {\n          destinationCoder = input.getPipeline().getCoderRegistry().getCoder(destinationT);\n        } catch (CannotProvideCoderException e) {\n          throw new IllegalArgumentException(\n              \"Unable to infer a coder for destination type (inferred from .by() as \\\"\"\n                  + destinationT\n                  + \"\\\") - specify it explicitly using .withDestinationCoder()\");\n        }\n      }\n      return destinationCoder;\n    }\n\n    private Collection<PCollectionView<?>> getAllSideInputs() {\n      return Requirements.union(getDestinationFn(), getOutputFn(), getSinkFn(), getFileNamingFn())\n          .getSideInputs();\n    }\n\n    private static class ViaFileBasedSink<UserT, DestinationT, OutputT>\n        extends FileBasedSink<UserT, DestinationT, OutputT> {\n      private final Write<DestinationT, UserT> spec;\n\n      private ViaFileBasedSink(Write<DestinationT, UserT> spec) {","sourceCodeStart":1546,"sourceCodeEnd":1582,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/io/FileIO.java#L1546-L1582","documentation":"FileIO.Write needs a Coder to serialize each destination object, and the CoderRegistry could not infer one from the type descriptor produced by the .by() destination function. Beam requires an explicit coder when the destination type is not a standard serializable type.","triggerScenarios":"Calling FileIO.<T>write/writeDynamic().by(fn) where the destination type (DestinationT) is a custom class without a registered coder and without calling .withDestinationCoder() before expansion.","commonSituations":"Using .by() with a lambda returning a custom POJO or a class lacking a default coder; forgetting withDestinationCoder when switching destination types; Kotlin/Scala data classes without registered coders.","solutions":["Call .withDestinationCoder(Coder) on the Write transform with a coder for your destination type","Make the destination type a simple codable type (String, KV, Avro record, etc.) or annotate it with @DefaultCoder","Register a custom CoderProvider in the CoderRegistry via pipeline options"],"exampleFix":"// before\nWriteFile<String> write = FileIO.<String>write().by(name -> new MyDest(name)).to(...);\n// after\nWriteFile<String> write = FileIO.<String>write()\n    .by(name -> new MyDest(name))\n    .withDestinationCoder(new MyDestCoder())\n    .to(...);","handlingStrategy":"validation","validationCode":"// Verify a coder can be inferred before building the transform\ntry {\n  pipeline.getCoderRegistry().getCoder(TypeDescriptor.of(MyDest.class));\n} catch (CannotProvideCoderException e) {\n  throw new IllegalStateException(\"Register a coder for MyDest via withDestinationCoder\", e);\n}","typeGuard":"static <T> boolean hasCoder(Pipeline p, TypeDescriptor<T> t) {\n  try { p.getCoderRegistry().getCoder(t); return true; }\n  catch (CannotProvideCoderException e) { return false; }\n}","tryCatchPattern":"try {\n  return pipeline.apply(FileIO.<String>write().by(fn).to(out));\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"Unable to infer a coder for destination type\")) {\n    throw new IllegalStateException(\"Call .withDestinationCoder()\", e);\n  }\n  throw e;\n}","preventionTips":["Prefer String/KV/Avro destination types that have default coders","Annotate custom destination classes with @DefaultCoder","Always pair custom .by() types with .withDestinationCoder()","Test dynamic-write pipelines with small DirectRunner runs before production"],"tags":["java","apache-beam","coder","serialization","file-io"],"backgroundTag":"missing-required-argument","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"}