{"record":{"id":"c02430a018f3a418","repo":"apache/beam","slug":"s-is-splittable-and-uses-state-but-these-are-not-compatible","errorCode":null,"errorMessage":"%s is splittable and uses state, but these are not compatible","messagePattern":"(.+?) is splittable and uses state, but these are not compatible","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ParDo.java","lineNumber":618,"sourceCode":"          methodSignature.windowT().isSupertypeOf(actualWindowT),\n          \"%s unable to provide window -- expected window type from parameter (%s) is not a \"\n              + \"supertype of actual window type assigned by windowing (%s)\",\n          methodSignature.targetMethod(),\n          methodSignature.windowT(),\n          actualWindowT);\n    }\n  }\n\n  /**\n   * Perform common validations of the {@link DoFn}, for example ensuring that state is used\n   * correctly and that its features can be supported.\n   */\n  private static <InputT, OutputT> void validate(DoFn<InputT, OutputT> fn) {\n    DoFnSignature signature = DoFnSignatures.getSignature((Class) fn.getClass());\n\n    // State is semantically incompatible with splitting\n    if (!signature.stateDeclarations().isEmpty() && signature.processElement().isSplittable()) {\n      throw new UnsupportedOperationException(\n          String.format(\n              \"%s is splittable and uses state, but these are not compatible\",\n              fn.getClass().getName()));\n    }\n\n    // Timers are semantically incompatible with splitting\n    if ((!signature.timerDeclarations().isEmpty() || !signature.timerFamilyDeclarations().isEmpty())\n        && signature.processElement().isSplittable()) {\n      throw new UnsupportedOperationException(\n          String.format(\n              \"%s is splittable and uses timers, but these are not compatible\",\n              fn.getClass().getName()));\n    }\n\n    // TimerFamily is semantically incompatible with splitting\n    if (!signature.timerFamilyDeclarations().isEmpty()\n        && signature.processElement().isSplittable()) {\n      throw new UnsupportedOperationException(","sourceCodeStart":600,"sourceCodeEnd":636,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/ParDo.java#L600-L636","documentation":"ParDo.validate inspects the DoFn signature at pipeline construction time and rejects DoFns that both declare state and are splittable, because Beam's model considers splitting an element incompatible with per-element state semantics. The transform cannot be built and construction fails with UnsupportedOperationException.","triggerScenarios":"Calling ParDo.of(fn) (which invokes validate) where fn's class declares @StateId fields AND its @ProcessElement is splittable (has a RestrictionTracker / @GetInitialRestriction watermarks etc.).","commonSituations":"Adding @StateId to an existing splittable DoFn (e.g. a file/splittable reader DoFn) assuming state works; combining libraries' SDF patterns with stateful processing.","solutions":["Remove the state declarations from the splittable DoFn, or remove splittable processing (RestrictionTracker) from the stateful DoFn","Split the logic into two DoFns: a splittable one producing elements, then a separate stateful ParDo","Restructure to track progress via the restriction itself rather than persistent state"],"exampleFix":"// before\nclass Sdf extends DoFn<T, O> { @StateId ... ; @ProcessElement ProcessContinuation processElement(RestrictionTracker r, ...) }\n// after\nclass Sdf extends DoFn<T, O> { @ProcessElement ProcessContinuation processElement(RestrictionTracker r, ...) } // state moved to downstream stateful DoFn","handlingStrategy":"validation","validationCode":"DoFnSignature sig = DoFnSignatures.getSignature((Class) fn.getClass());\nif (!sig.stateDeclarations().isEmpty() && sig.processElement().isSplittable()) {\n  throw new IllegalArgumentException(fn.getClass() + \" cannot use state and be splittable\");\n}","typeGuard":"boolean stateAndSplittable(DoFn<?, ?> fn) {\n  DoFnSignature sig = DoFnSignatures.getSignature((Class) fn.getClass());\n  return !sig.stateDeclarations().isEmpty() && sig.processElement().isSplittable();\n}","tryCatchPattern":"try {\n  pipeline.apply(ParDo.of(fn));\n} catch (UnsupportedOperationException e) {\n  if (e.getMessage() != null && e.getMessage().endsWith(\"splittable and uses state, but these are not compatible\")) {\n    throw new IllegalStateException(\"Split into splittable read + separate stateful ParDo\", e);\n  }\n  throw e;\n}","preventionTips":["Review DoFn signatures before combining state with RestrictionTracker usage","Keep stateful logic in non-splittable DoFns","Add pipeline-construction unit tests that catch validate() errors early"],"tags":["java","apache-beam","splittable-dofn","state"],"backgroundTag":"conflicting-config-options","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"}