{"record":{"id":"c285d8a0fe0e3eff","repo":"apache/beam","slug":"cannot-access-key-as-parameter-outside-of-ontimer-method","errorCode":null,"errorMessage":"Cannot access key as parameter outside of @OnTimer method.","messagePattern":"Cannot access key as parameter outside of @OnTimer method\\.","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/DoFnTester.java","lineNumber":310,"sourceCode":"            public DoFn<InputT, OutputT>.FinishBundleContext finishBundleContext(\n                DoFn<InputT, OutputT> doFn) {\n              throw new UnsupportedOperationException(\n                  \"Not expected to access DoFn.FinishBundleContext from @ProcessElement\");\n            }\n\n            @Override\n            public DoFn<InputT, OutputT>.ProcessContext processContext(DoFn<InputT, OutputT> doFn) {\n              return processContext;\n            }\n\n            @Override\n            public InputT element(DoFn<InputT, OutputT> doFn) {\n              return processContext.element();\n            }\n\n            @Override\n            public Object key() {\n              throw new UnsupportedOperationException(\n                  \"Cannot access key as parameter outside of @OnTimer method.\");\n            }\n\n            @Override\n            public Instant timestamp(DoFn<InputT, OutputT> doFn) {\n              return processContext.timestamp();\n            }\n\n            @Override\n            public String timerId(DoFn<InputT, OutputT> doFn) {\n              throw new UnsupportedOperationException(\n                  \"Cannot access timerId as parameter outside of @OnTimer method.\");\n            }\n\n            @Override\n            public TimeDomain timeDomain(DoFn<InputT, OutputT> doFn) {\n              throw new UnsupportedOperationException(\n                  \"Not expected to access TimeDomain from @ProcessElement\");","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/transforms/DoFnTester.java#L292-L328","documentation":"The key() context parameter is only injectable inside @OnTimer methods (and keyed contexts). DoFnTester's ProcessContext throws UnsupportedOperationException if a @ProcessElement method declares the key as a parameter, because element processing in the tester isn't keyed.","triggerScenarios":"Declaring `Object key` (DoFn.Key parameter) in a @ProcessElement method and running it under DoFnTester.","commonSituations":"Testing stateful/timer DoFns with DoFnTester; accidentally requesting the key in element processing when the pipeline runs with unkeyed input.","solutions":["Access the key in @OnTimer methods only, or obtain the key from a KV input (c.element().getKey()) in @ProcessElement","Remove the key parameter from @ProcessElement; use @Element KV<K,V> and extract the key","For stateful processing tests, run via TestPipeline with a real runner instead of DoFnTester"],"exampleFix":"// before\n@ProcessElement public void process(@Element KV<String, Integer> e, @Key String key) {...}\n// after\n@ProcessElement public void process(@Element KV<String, Integer> e) { String key = e.getKey(); ... }","handlingStrategy":"validation","validationCode":"// key() is only injectable in @OnTimer contexts; derive key from KV in @ProcessElement\nString key = kv.getKey();","typeGuard":null,"tryCatchPattern":"try {\n  tester.processElement();\n} catch (UnsupportedOperationException e) {\n  // @Key parameter used in @ProcessElement\n}","preventionTips":["Use @Key only in @OnTimer methods","Extract keys from KV elements in @ProcessElement"],"tags":["apache-beam","java","testing","dofn","stateful-processing"],"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"}