{"record":{"id":"8624ebf293d1f5e9","repo":"oracle/graal","slug":"unbalanced-monitors-monitors-do-not-match","errorCode":null,"errorMessage":"unbalanced monitors - monitors do not match","messagePattern":"unbalanced monitors - monitors do not match","errorType":"exception","errorClass":"PermanentBailoutException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/FrameStateBuilder.java","lineNumber":518,"sourceCode":"        }\n        for (int i = 0; i < stackSize(); i++) {\n            ValueNode x = stack[i];\n            ValueNode y = other.stack[i];\n            assert x != null;\n            assert y != null;\n            if (x != y && (x == TWO_SLOT_MARKER || x.isDeleted() || y == TWO_SLOT_MARKER || y.isDeleted() || x.getStackKind() != y.getStackKind())) {\n                throw new GraalError(incompatibilityErrorMessage(\"mismatch in stack types\", other));\n            }\n        }\n        if (lockedObjects.length != other.lockedObjects.length) {\n            throw new PermanentBailoutException(incompatibilityErrorMessage(\"unbalanced monitors - locked objects do not match\", other));\n        }\n        for (int i = 0; i < lockedObjects.length; i++) {\n            if (monitorIds[i] != other.monitorIds[i]) {\n                if (MonitorIdNode.monitorIdentityEquals(monitorIds[i], other.monitorIds[i])) {\n                    continue;\n                }\n                throw new PermanentBailoutException(incompatibilityErrorMessage(\"unbalanced monitors - monitors do not match\", other));\n            }\n        }\n    }\n\n    public boolean areLocksMergeableWith(FrameStateBuilder other) {\n        if (lockedObjects.length != other.lockedObjects.length) {\n            return false;\n        }\n        for (int i = 0; i < lockedObjects.length; i++) {\n            if (!MonitorIdNode.monitorIdentityEquals(monitorIds[i], other.monitorIds[i])) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    public void merge(AbstractMergeNode block, FrameStateBuilder other) {\n        checkCompatibleWith(other);","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/FrameStateBuilder.java#L500-L536","documentation":"Companion of the locked-object-count check: both predecessors hold the same number of monitors, but at some index the monitor identities cannot be reconciled (different monitorIds and MonitorIdNode.monitorIdentityEquals fails). Even matching counts are not enough — the same locks, identified by their locking objects, must be held at the merge, otherwise Graal permanently bails out.","triggerScenarios":"The per-index loop over lockedObjects at a merge finding monitorIds[i] != other.monitorIds[i] with different underlying lock identity — e.g. two branches each did monitorenter on different objects and then flow together.","commonSituations":"Generated/obfuscated bytecode locking different objects on different branches before a join; instrumentation inserting conditional monitors; malformed monitorenter sequences that pass naive count checks but lock distinct objects.","solutions":["Strictly verify the class to locate the offending merge and method.","Restructure the code so the same lock object(s) are held on every path reaching the merge (lock before branching, or unlock before the join).","Regenerate the bytecode without the tool transformation that introduced the divergent locks."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// ensure the same lock object is held on all paths into a merge;\n// strict verification catches mismatched monitor identities early","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lock before branching or unlock before joining, never conditionally inside branches.","Verify instrumented classes after obfuscation/coverage transformations."],"tags":["graalvm","bytecode-verification","monitors","merge","bailout"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}