{"record":{"id":"58893ea5dc906456","repo":"apache/beam","slug":"runtimeexception-mutationdetectors","errorCode":null,"errorMessage":"RuntimeException","messagePattern":"RuntimeException","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/util/MutationDetectors.java","lineNumber":130,"sourceCode":"     */\n    public CodedValueMutationDetector(T value, Coder<T> coder) throws CoderException {\n      this.coder = coder;\n      // We need to clone the original value before getting it's structural value.\n      // If the object is consistent with equals, the Structural value will be the\n      // exact same object reference making it impossible to detect changes.\n      clonedOriginalValue = CoderUtils.clone(coder, value);\n      this.originalStructuralValue = coder.structuralValue(clonedOriginalValue);\n      this.possiblyModifiedObject = value;\n      this.encodedOriginalObject = CoderUtils.encodeToByteArray(coder, value);\n      this.clonedOriginalObject = CoderUtils.decodeFromByteArray(coder, encodedOriginalObject);\n    }\n\n    @Override\n    public void verifyUnmodified() {\n      try {\n        verifyUnmodifiedThrowingCheckedExceptions();\n      } catch (CoderException exn) {\n        throw new RuntimeException(exn);\n      }\n    }\n\n    private void verifyUnmodifiedThrowingCheckedExceptions() throws CoderException {\n      // Since there is no guarantee that cloning an object via the coder will\n      // return the exact same type as value, We are cloning the possiblyModifiedObject\n      // before getting it's structural value. This way we are guaranteed to compare the same\n      // types.\n      T possiblyModifiedClonedValue = CoderUtils.clone(coder, possiblyModifiedObject);\n      Object newStructuralValue = coder.structuralValue(possiblyModifiedClonedValue);\n      if (originalStructuralValue.equals(newStructuralValue)) {\n        return;\n      } else if (Objects.deepEquals(\n          encodedOriginalObject, CoderUtils.encodeToByteArray(coder, possiblyModifiedObject))) {\n        LOG.warn(\n            \"{} of type {} has a #structuralValue method which does not return true when the \"\n                + \"encoding of the elements is equal. Element {}\",\n            Coder.class.getSimpleName(),","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/util/MutationDetectors.java#L112-L148","documentation":"MutationDetectors' verifyUnmodified re-encodes the original value and compares it with the possibly-mutated value to detect illegal mutations. CoderException (a checked exception) can occur while re-encoding; since verifyUnmodified cannot throw checked exceptions, it is wrapped in a plain RuntimeException.","triggerScenarios":"Calling verifyUnmodified() (directly or via close()) on a CheckedMutationDetector when the coder fails to encode the original or cloned value — e.g. a value whose encoded form the coder cannot round-trip.","commonSituations":"Custom coders that are non-deterministic or fail on cloned values; elements whose encoding changed between Beam versions.","solutions":["Inspect getCause() for the underlying CoderException.","Ensure your coder is deterministic and can encode both the original and cloned value.","Use a deep copy or re-create the value instead of mutating it before close()."],"exampleFix":"// before\ndetector.verifyUnmodified();\n// after\ntry { detector.verifyUnmodified(); } catch (RuntimeException e) { throw new RuntimeException(e.getCause()); }","handlingStrategy":"try-catch","validationCode":"// before verifyUnmodified:\n// byte[] orig = CoderUtils.encodeToBase64(coder, value);\n// CoderUtils.decodeFromBase64(coder, orig); // ensure coder round-trips","typeGuard":"null","tryCatchPattern":"try { detector.verifyUnmodified(); } catch (RuntimeException e) { CoderException ce = (CoderException) e.getCause(); /* handle coder failure */ }","preventionTips":["Write deterministic coders that round-trip cloned values","Test coders with CoderTester for your element types","Avoid values whose encoding depends on mutable JVM state"],"tags":["java","coders"],"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-20T03:17:13.778Z"}