{"record":{"id":"c92e60e1064c17a9","repo":"apache/beam","slug":"expected-that-the-coder-is-deterministic","errorCode":null,"errorMessage":"Expected that the coder is deterministic","messagePattern":"Expected that the coder is deterministic","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/testing/CoderProperties.java","lineNumber":85,"sourceCode":"   * Verifies that for the given {@code Coder<T>}, and values of type {@code T}, if the values are\n   * equal then the encoded bytes are equal, in any {@code Coder.Context}.\n   */\n  public static <T> void coderDeterministic(Coder<T> coder, T value1, T value2) throws Exception {\n    for (Coder.Context context : ALL_CONTEXTS) {\n      coderDeterministicInContext(coder, context, value1, value2);\n    }\n  }\n\n  /**\n   * Verifies that for the given {@code Coder<T>}, {@code Coder.Context}, and values of type {@code\n   * T}, if the values are equal then the encoded bytes are equal.\n   */\n  public static <T> void coderDeterministicInContext(\n      Coder<T> coder, Coder.Context context, T value1, T value2) throws Exception {\n    try {\n      coder.verifyDeterministic();\n    } catch (NonDeterministicException e) {\n      throw new AssertionError(\"Expected that the coder is deterministic\", e);\n    }\n    assertThat(\"Expected that the passed in values are equal()\", value1, equalTo(value2));\n    assertThat(encode(coder, context, value1), equalTo(encode(coder, context, value2)));\n  }\n\n  /**\n   * Verifies that for the given {@code Coder<T>}, and value of type {@code T}, encoding followed by\n   * decoding yields an equal value of type {@code T}, in any {@code Coder.Context}.\n   */\n  public static <T> void coderDecodeEncodeEqual(Coder<T> coder, T value) throws Exception {\n    for (Coder.Context context : ALL_CONTEXTS) {\n      coderDecodeEncodeEqualInContext(coder, context, value);\n    }\n  }\n\n  /**\n   * Verifies that for the given {@code Coder<T>}, {@code Coder.Context}, and value of type {@code\n   * T}, encoding followed by decoding yields an equal value of type {@code T}.","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/testing/CoderProperties.java#L67-L103","documentation":"CoderProperties.coderDeterministicInContext is a test utility asserting that a Coder is deterministic. It calls coder.verifyDeterministic() and, when the coder reports NonDeterministicException, converts it into an AssertionError with this message. The library throws it because deterministic coding is a correctness prerequisite for Beam's grouping/windowing operations.","triggerScenarios":"Calling CoderProperties.coderDeterministic(...) or coderDeterministicInContext(coder, context, value1, value2) in a unit test where coder.verifyDeterministic() throws NonDeterministicException (e.g. double, BigDecimal, or custom coders that encode unordered structures).","commonSituations":"Writing custom coder tests for coders over doubles, maps, or user classes whose encoded form depends on iteration order; accidentally testing a non-deterministic coder with this assertion helper.","solutions":["Fix the coder to be deterministic: sort elements before encoding, or use a deterministic representation","If the coder legitimately cannot be deterministic, do not assert determinism; test encode/decode round-tripping only (e.g. CoderProperties.coderDecodeEncodeEqual)","Wrap the non-deterministic part with a deterministic delegate (e.g. via Docker-like ordered encodings or WritableCoder over a canonical form)"],"exampleFix":"// before\ncoder = new MapCoder<>(StringUtf8Coder.of(), DoubleCoder.of());\nCoderProperties.coderDeterministic(coder, mapValue1, mapValue2);\n// after\ncoder = OrderedCoderedMapCoder // or sort entries in encode()\nCoderProperties.coderDeterministic(sortedMapCoder, mapValue1, mapValue2);","handlingStrategy":"validation","validationCode":"try {\n  coder.verifyDeterministic();\n} catch (NonDeterministicException e) {\n  throw new IllegalStateException(\"Refusing determinism test: \" + e.getMessage(), e);\n}","typeGuard":"boolean isDeterministicSafe(Coder<?> coder) {\n  return coder.consistentWithEquals() && !(coder instanceof DoubleCoder)\n      && !(coder instanceof BigDecimalCoder);\n}","tryCatchPattern":"try {\n  CoderProperties.coderDeterministic(coder, v1, v2);\n} catch (AssertionError e) {\n  throw new AssertionError(\"Coder \" + coder + \" is non-deterministic: fix encode() ordering\", e.getCause());\n}","preventionTips":["Sort/map contents deterministically inside custom coders before encoding","Avoid DoubleCoder/BigDecimal coders in keys or grouping inputs","Run verifyDeterministic() early in coder development, before wiring into pipelines"],"tags":["apache-beam","coder","determinism","testing"],"backgroundTag":"internal-invariant-violation","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"}