{"record":{"id":"668104a80fc61f25","repo":"apache/beam","slug":"unable-to-get-key-coder","errorCode":null,"errorMessage":"Unable to get key coder","messagePattern":"Unable to get key coder","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/ordered/src/main/java/org/apache/beam/sdk/extensions/ordered/OrderedEventProcessor.java","lineNumber":116,"sourceCode":"  @Override\n  public OrderedEventProcessorResult<EventKeyT, ResultT, EventT> expand(\n      PCollection<KV<EventKeyT, KV<Long, EventT>>> input) {\n    final TupleTag<KV<EventKeyT, ResultT>> mainOutput =\n        new TupleTag<KV<EventKeyT, ResultT>>(\"mainOutput\") {};\n    final TupleTag<KV<EventKeyT, OrderedProcessingStatus>> statusOutput =\n        new TupleTag<KV<EventKeyT, OrderedProcessingStatus>>(\"status\") {};\n\n    final TupleTag<KV<EventKeyT, KV<Long, UnprocessedEvent<EventT>>>> unprocessedEventOutput =\n        new TupleTag<KV<EventKeyT, KV<Long, UnprocessedEvent<EventT>>>>(\"unprocessed-events\") {};\n\n    OrderedProcessingHandler<EventT, EventKeyT, StateT, ResultT> handler = getHandler();\n    Pipeline pipeline = input.getPipeline();\n\n    Coder<EventKeyT> keyCoder;\n    try {\n      keyCoder = handler.getKeyCoder(pipeline, input.getCoder());\n    } catch (CannotProvideCoderException e) {\n      throw new RuntimeException(\"Unable to get key coder\", e);\n    }\n\n    Coder<EventT> eventCoder;\n    try {\n      eventCoder = handler.getEventCoder(pipeline, input.getCoder());\n    } catch (CannotProvideCoderException e) {\n      throw new RuntimeException(\"Unable to get event coder\", e);\n    }\n\n    Coder<StateT> stateCoder;\n    try {\n      stateCoder = handler.getStateCoder(pipeline);\n    } catch (CannotProvideCoderException e) {\n      throw new RuntimeException(\"Unable to get state coder\", e);\n    }\n\n    Coder<ResultT> resultCoder;\n    try {","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/ordered/src/main/java/org/apache/beam/sdk/extensions/ordered/OrderedEventProcessor.java#L98-L134","documentation":"OrderedEventProcessor.expand() asks the ComposedAccumulatingProcessingHandler for a Coder for the key type EventKeyT. If the handler cannot infer it from the input PCollection's KvCoder (CannotProvideCoderException), expansion fails with this RuntimeException. Beam requires concrete coders to serialize data between stages, so expansion aborts early rather than failing at runtime.","triggerScenarios":"Applying OrderedEventProcessor.expand() to a PCollection<KV<EventKeyT, EventT>> whose key coder cannot be inferred — e.g. the input was created without a key coder, the key type's type token is erased, or no registered CoderProvider exists for the key type.","commonSituations":"Using a custom key class without a CoderProvider registered (CoderRegistry not extended); creating the input with Create.of and generics erasure losing the exact key type; using a lambda/anonymous type whose type descriptor cannot be resolved.","solutions":["Ensure the input PCollection uses a KvCoder, e.g. apply(\"setKeyCoder\", Keys IGNORED) — actually wrap with PCollection.is/applyCoder: use PCollectionLists or KvCoder.of(keyCoder, eventCoder) via setCoder() on the input before expansion.","Register a CoderProvider for your custom key type via CoderRegistry.registerCoderProvider or annotate with @DefaultCoder.","Implement getKeyCoder in your handler subclass to supply an explicit coder instead of relying on inference.","Check for generics erasure: capture the concrete key TypeDescriptor when building the pipeline."],"exampleFix":"// before\nPCollection<KV<MyKey, Event>> input = events;\nprocessor.expand(input); // CannotProvideCoderException for MyKey\n\n// after\nPCollection<KV<MyKey, Event>> input = events.setCoder(KvCoder.of(MyKeyCoder.of(), EventCoder.of()));\nprocessor.expand(input);","handlingStrategy":"validation","validationCode":"if (!(input.getCoder() instanceof KvCoder)) {\n  throw new IllegalArgumentException(\"input must be coded with KvCoder<K, V>; set it via input.setCoder(...)\");\n}\nKvCoder<?, ?> kv = (KvCoder<?, ?>) input.getCoder();\nif (kv.getKeyCoder() == null) { throw new IllegalArgumentException(\"missing key coder\"); }","typeGuard":"static boolean hasKeyCoder(PCollection<?> pc) {\n  return pc.getCoder() instanceof KvCoder && ((KvCoder<?, ?>) pc.getCoder()).getKeyCoder() != null;\n}","tryCatchPattern":"try {\n  pipeline.apply(processor);\n} catch (RuntimeException e) {\n  if (e.getCause() instanceof CannotProvideCoderException) {\n    throw new IllegalStateException(\"Register a CoderProvider or set an explicit KvCoder on the input\", e);\n  }\n  throw e;\n}","preventionTips":["Always set an explicit KvCoder on inputs to OrderedEventProcessor","Register CoderProviders for all custom key types at pipeline setup","Add a pipeline-construction unit test that expands the processor"],"tags":["apache-beam","coder","serialization","pipeline-construction"],"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"}