{"record":{"id":"ee1d3c8d3474face","repo":"apache/beam","slug":"cannot-call-sideinput-in-a-null-context-ee1d3c","errorCode":null,"errorMessage":"cannot call sideInput() in a null context","messagePattern":"cannot call sideInput\\(\\) in a null context","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/util/CombineContextFactory.java","lineNumber":39,"sourceCode":"import org.apache.beam.sdk.options.PipelineOptions;\nimport org.apache.beam.sdk.state.StateContext;\nimport org.apache.beam.sdk.transforms.CombineWithContext.Context;\nimport org.apache.beam.sdk.values.PCollectionView;\n\n/** Factory that produces {@code Combine.Context} based on different inputs. */\n@Internal\npublic class CombineContextFactory {\n\n  private static final Context NULL_CONTEXT =\n      new Context() {\n        @Override\n        public PipelineOptions getPipelineOptions() {\n          throw new IllegalArgumentException(\"cannot call getPipelineOptions() in a null context\");\n        }\n\n        @Override\n        public <T> T sideInput(PCollectionView<T> view) {\n          throw new IllegalArgumentException(\"cannot call sideInput() in a null context\");\n        }\n      };\n\n  /** Returns a fake {@code Combine.Context} for tests. */\n  public static Context nullContext() {\n    return NULL_CONTEXT;\n  }\n\n  /** Returns a {@code Combine.Context} that wraps a {@link StateContext}. */\n  public static Context createFromStateContext(final StateContext<?> c) {\n    return new Context() {\n      @Override\n      public PipelineOptions getPipelineOptions() {\n        return c.getPipelineOptions();\n      }\n\n      @Override\n      public <T> T sideInput(PCollectionView<T> view) {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/util/CombineContextFactory.java#L21-L57","documentation":"The null Combine.Context placeholder also rejects sideInput(view) with this IllegalArgumentException, because a null context carries no side inputs. Any attempt to read a side input while combining under the null context fails immediately.","triggerScenarios":"Calling context.sideInput(someView) inside a CombineFn (addInput, mergeAccumulators, extractOutput, or accessor) when the Combine operation was configured with CombineContextFactory.nullContext().","commonSituations":"CombineFn logic that reads side inputs being unit-tested with nullContext(); a pipeline using Combine.globally/PerKey with contexts bound to null while the combine function expects side inputs.","solutions":["Pass a real Context whose sideInput returns test fixtures when testing side-input-aware CombineFns","Split the CombineFn so side-input logic is not exercised in null-context paths, or guard sideInput calls on availability","Wire the pipeline so the combine step is bound to a context containing the required side inputs (e.g. via CombineFnUtil.bindContext with a non-null context)"],"exampleFix":"// before\nContext ctx = CombineContextFactory.nullContext();\nT side = ctx.sideInput(view); // throws\n// after\nContext ctx = new Context() {\n  public PipelineOptions getPipelineOptions() { throw new UnsupportedOperationException(); }\n  public <T> T sideInput(PCollectionView<T> v) { return testSideInputs.get(v); }\n};\nT side = ctx.sideInput(view);","handlingStrategy":"validation","validationCode":"if (requiresSideInputs) {\n  // do not use nullContext()\n  Context ctx = makeContextWithSideInputs(testViews);\n}","typeGuard":null,"tryCatchPattern":"try {\n  T side = context.sideInput(view);\n} catch (IllegalArgumentException e) {\n  // bound with null context: side inputs are unavailable here\n}","preventionTips":["Keep side-input-reading CombineFns out of null-context tests","Provide a fake Context supplying fixture side inputs","Verify pipeline wiring binds the combine to a contextful call with declared side inputs"],"tags":["java","beam","combine","side-inputs","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-14T16:17:12.679Z"}