{"record":{"id":"65c7671e49a96306","repo":"apache/beam","slug":"processcontext-unsupported-in-context","errorCode":null,"errorMessage":"ProcessContext unsupported in ${context}","messagePattern":"ProcessContext unsupported in (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnInvoker.java","lineNumber":306,"sourceCode":"     */\n    TimerMap timerFamily(String tagId);\n\n    /**\n     * Returns the timer id for the current timer of a {@link\n     * org.apache.beam.sdk.transforms.DoFn.TimerFamily}.\n     */\n    String timerId(DoFn<InputT, OutputT> doFn);\n  }\n\n  /**\n   * This {@link ArgumentProvider} throws {@link UnsupportedOperationException} for all parameters.\n   */\n  @Internal\n  abstract class BaseArgumentProvider<InputT, OutputT>\n      implements ArgumentProvider<InputT, OutputT> {\n    @Override\n    public DoFn<InputT, OutputT>.ProcessContext processContext(DoFn<InputT, OutputT> doFn) {\n      throw new UnsupportedOperationException(\n          String.format(\"ProcessContext unsupported in %s\", getErrorContext()));\n    }\n\n    @Override\n    public InputT element(DoFn<InputT, OutputT> doFn) {\n      throw new UnsupportedOperationException(\n          String.format(\"Element unsupported in %s\", getErrorContext()));\n    }\n\n    @Override\n    public @Nullable Object key() {\n      throw new UnsupportedOperationException(\n          \"Cannot access key as parameter outside of @OnTimer method.\");\n    }\n\n    @Override\n    public @Nullable Object sideInput(String tagId) {\n      throw new UnsupportedOperationException(","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/reflect/DoFnInvoker.java#L288-L324","documentation":"DoFnInvoker.BaseArgumentProvider provides a default ArgumentProvider whose processContext() always throws UnsupportedOperationException. The Beam pipeline machinery substitutes a real, context-aware ArgumentProvider when a method actually needs a ProcessContext; hitting this default means the surrounding context does not support ProcessContext access.","triggerScenarios":"Calling doFn.processContext(...) (or invoking a method that requests a ProcessContext parameter) with the default BaseArgumentProvider that was not replaced — e.g. invoking a DoFn method in a context that is not a proper element-processing step, or tests calling methods directly with a plain invoker.","commonSituations":"Unit tests that construct a DoFnInvoker with the default BaseArgumentProvider and then call methods requiring a ProcessContext; calling a @ProcessElement-style method from @StartBundle/@FinishBundle where only bundle context is available; runner-side bugs invoking a DoFn with the wrong ArgumentProvider.","solutions":["Check where the DoFn method is being invoked: access ProcessContext only from @ProcessElement methods","In tests, provide a stub ArgumentProvider that overrides processContext() instead of using BaseArgumentProvider defaults","Use DoFnInvokers.invokerForFn() / the generated invoker so Beam installs the correct ArgumentProvider","If you own the runner/integration code, pass an ArgumentProvider that implements processContext()"],"exampleFix":"// before (test stub)\nnew DoFnInvoker.BaseArgumentProvider<String, String>() {};\n// after\nnew DoFnInvoker.BaseArgumentProvider<String, String>() {\n  @Override\n  public DoFn<String, String>.ProcessContext processContext(DoFn<String, String> doFn) {\n    return fakeProcessContext; // supplied by the test harness\n  }\n};","handlingStrategy":"type-guard","validationCode":"// Only access ProcessContext from @ProcessElement methods:\nboolean inProcessElement = method.isAnnotationPresent(org.apache.beam.sdk.transforms.DoFn.ProcessElement.class);\nif (!inProcessElement) {\n  throw new IllegalStateException(\"ProcessContext is only available in @ProcessElement\");\n}","typeGuard":"static boolean hasProcessContext(DoFnInvoker.ArgumentProvider<?, ?> p) {\n  try { p.processContext(null); return true; }\n  catch (UnsupportedOperationException e) { return false; }\n}","tryCatchPattern":"try {\n  doFnInvoker.invokeProcessElement(args);\n} catch (UnsupportedOperationException e) {\n  throw new IllegalStateException(\n      \"ProcessContext unavailable here (\" + e.getMessage() + \"); move access into @ProcessElement\", e);\n}","preventionTips":["Access ProcessContext only inside @ProcessElement methods","Use OnTimerContext/StartBundleContext types as declared by each callback","In tests, stub processContext()/element() instead of using bare BaseArgumentProvider","Prefer DoFnInvokers.invokerForFn() so Beam installs the correct provider"],"tags":["java","unsupported-operation","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"}