{"record":{"id":"3568dc886790a72c","repo":"apache/beam","slug":"parameter-s-not-supported-by-dofntester","errorCode":null,"errorMessage":"Parameter %s not supported by DoFnTester","messagePattern":"Parameter (.+?) not supported by DoFnTester","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/DoFnTester.java","lineNumber":877,"sourceCode":"            @Override\n            public @Nullable Void dispatch(\n                DoFnSignature.Parameter.TaggedOutputReceiverParameter p) {\n              return null;\n            }\n\n            @Override\n            public @Nullable Void dispatch(DoFnSignature.Parameter.PaneInfoParameter p) {\n              return null;\n            }\n\n            @Override\n            public Void dispatch(DoFnSignature.Parameter.TimerIdParameter p) {\n              return null;\n            }\n\n            @Override\n            protected Void dispatchDefault(DoFnSignature.Parameter p) {\n              throw new UnsupportedOperationException(\n                  \"Parameter \" + p + \" not supported by DoFnTester\");\n            }\n          });\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  private void initializeState() throws Exception {\n    checkState(state == State.UNINITIALIZED, \"Already initialized\");\n    checkState(fn == null, \"Uninitialized but fn != null\");\n    if (cloningBehavior.equals(CloningBehavior.DO_NOT_CLONE)) {\n      fn = origFn;\n    } else {\n      fn =\n          (DoFn<InputT, OutputT>)\n              SerializableUtils.deserializeFromByteArray(\n                  SerializableUtils.serializeToByteArray(origFn), origFn.toString());\n    }","sourceCodeStart":859,"sourceCodeEnd":895,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/DoFnTester.java#L859-L895","documentation":"DoFnTester simulates only a subset of DoFn parameter types. When preparing a context method (e.g. @ProcessElement) whose signature requires a parameter type it doesn't handle (anything beyond timer-id, timestamp, window, etc.), it throws this UnsupportedOperationException naming the parameter.","triggerScenarios":"Using DoFnTester on a DoFn whose ProcessElement/OnTimer method takes unsupported parameters such as RestrictionTracker, WatermarkEstimator, BundleFinalizer, or Timer/TimeDomain parameters.","commonSituations":"Unit-testing a splittable DoFn or a stateful/timer DoFn with DoFnTester; Beam version upgrades where a new parameter type was added before DoFnTester support.","solutions":["Refactor the DoFn so core logic is in a plain method testable without the unsupported parameter","Use TestPipeline (mini-runner) instead of DoFnTester for stateful/SDF/timer-based DoFns","Move state/timer interactions behind an interface and mock it in unit tests"],"exampleFix":"// before\ntester.processElement(...); // DoFn takes RestrictionTracker parameter\n// after\nTestPipeline p = TestPipeline.create();\np.apply(...).apply(ParDo.of(new MySdf()));","handlingStrategy":"validation","validationCode":"// Inspect the ProcessElement method params before choosing DoFnTester\nfor (Method m : myDoFn.getClass().getDeclaredMethods()) {\n  if (m.isAnnotationPresent(DoFn.ProcessElement.class)) {\n    for (Class<?> p : m.getParameterTypes()) {\n      if (RestrictionTracker.class.isAssignableFrom(p)\n          || WatermarkEstimator.class.isAssignableFrom(p)\n          || Timer.class.isAssignableFrom(p)) {\n        throw new IllegalArgumentException(\"Use TestPipeline, not DoFnTester\");\n      }\n    }\n  }\n}","typeGuard":"boolean doFnTesterSupported(DoFn<?, ?> fn) {\n  return java.util.Arrays.stream(fn.getClass().getDeclaredMethods())\n      .filter(m -> m.isAnnotationPresent(DoFn.ProcessElement.class)\n                || m.isAnnotationPresent(DoFn.OnTimer.class))\n      .flatMap(m -> java.util.Arrays.stream(m.getParameterTypes()))\n      .noneMatch(p -> p.getSimpleName().equals(\"RestrictionTracker\")\n                   || p.getSimpleName().equals(\"WatermarkEstimator\"));\n}","tryCatchPattern":"try { tester.processElement(); }\ncatch (UnsupportedOperationException e) { /* switch to TestPipeline-based test */ }","preventionTips":["Refactor heavy logic out of the DoFn so unit tests don't need exotic parameters","Use DoFnTester only for simple element-wise DoFns","Any DoFn with timers, state, or restriction tracking should be tested via TestPipeline"],"tags":["java","apache-beam","dofn","testing"],"backgroundTag":"unsupported-operation","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"}