{"record":{"id":"eb6eb3334751d4d3","repo":"apache/beam","slug":"customcoder-implementations-must-override","errorCode":null,"errorMessage":"CustomCoder implementations must override verifyDeterministic, or they are presumed nondeterministic.","messagePattern":"CustomCoder implementations must override verifyDeterministic, or they are presumed nondeterministic\\.","errorType":"exception","errorClass":"NonDeterministicException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CustomCoder.java","lineNumber":49,"sourceCode":"\n  /**\n   * {@inheritDoc}.\n   *\n   * <p>Returns an empty list. A {@link CustomCoder} has no default argument {@link Coder coders}.\n   */\n  @Override\n  public List<? extends Coder<?>> getCoderArguments() {\n    return Collections.emptyList();\n  }\n\n  /**\n   * {@inheritDoc}\n   *\n   * @throws NonDeterministicException a {@link CustomCoder} is presumed nondeterministic.\n   */\n  @Override\n  public void verifyDeterministic() throws NonDeterministicException {\n    throw new NonDeterministicException(\n        this,\n        \"CustomCoder implementations must override verifyDeterministic,\"\n            + \" or they are presumed nondeterministic.\");\n  }\n\n  // This coder inherits isRegisterByteSizeObserverCheap,\n  // getEncodedElementByteSize and registerByteSizeObserver\n  // from Coder. Override if we can do better.\n}\n","sourceCodeStart":31,"sourceCodeEnd":59,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/coders/CustomCoder.java#L31-L59","documentation":"CustomCoder.verifyDeterministic is intentionally left throwing: any coder that does not override it is presumed nondeterministic, because determinism cannot be verified automatically. Beam throws NonDeterministicException whenever such a coder's verifyDeterministic() is called (e.g. during GBK / group-by-key planning on keyed PCollections).","triggerScenarios":"Subclassing CustomCoder without overriding verifyDeterministic and using the coder where Beam checks determinism — most commonly a keyed PCollection entering GroupByKey, Combine, or Join.","commonSituations":"Writing a first custom coder and forgetting the override; a coder that is actually deterministic but whose author never declared it; upgrading Beam so a determinism check newly runs on an existing coder.","solutions":["Override verifyDeterministic() as a no-op (or with component checks) if encoding is truly deterministic.","If genuinely nondeterministic, avoid operations requiring determinism (GBK) or switch to a deterministic key encoding.","For composite coders, delegate to component coders' verifyDeterministic inside your override."],"exampleFix":"// before\nclass MyCoder extends CustomCoder<MyT> { /* no verifyDeterministic */ }\n// after\nclass MyCoder extends CustomCoder<MyT> {\n  @Override\n  public void verifyDeterministic() throws NonDeterministicException {} // encoding is stable\n}","handlingStrategy":"try-catch","validationCode":"try {\n  myCoder.verifyDeterministic();\n} catch (NonDeterministicException e) {\n  // coder needs an override or must not be used as a key coder\n}","typeGuard":null,"tryCatchPattern":"try {\n  keyed.apply(GroupByKey.create());\n} catch (NonDeterministicException e) {\n  // override verifyDeterministic in your CustomCoder or pick a deterministic key coder\n}","preventionTips":["Always override verifyDeterministic when subclassing CustomCoder.","Call verifyDeterministic() in coder unit tests.","Only use deterministic coders for key types in GBK/Combine operations."],"tags":["java","apache-beam","coders","determinism"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T21:17:11.552Z"}