{"record":{"id":"c9f92d4fd81d2f34","repo":"oracle/graal","slug":"setting-ihashcode-of-an-object-whose-ihashcode-is","errorCode":null,"errorMessage":"Setting ihashcode of an object whose ihashcode is already initialized.","messagePattern":"Setting ihashcode of an object whose ihashcode is already initialized\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"espresso/src/org.graalvm.continuations/src/org/graalvm/continuations/IdentityHashCodes.java","lineNumber":95,"sourceCode":"     */\n    public static boolean trySet(Object o, int hashcode) {\n        checkIsSupported();\n        return setIHashcode0(o, hashcode);\n    }\n\n    /**\n     * Sets the identity hashcode of the given object if it is not already initialized, and throws\n     * {@link IllegalStateException} otherwise.\n     *\n     * @throws UnsupportedOperationException If this VM does not support continuations.\n     * @throws NullPointerException if {@code o} is {@code null}.\n     * @throws IllegalArgumentException if {@code hashcode <= 0}.\n     * @throws IllegalStateException if the identity hashcode of the given object is already\n     *             initialized.\n     */\n    public static void set(Object o, int hashcode) {\n        if (!trySet(o, hashcode)) {\n            throw new IllegalStateException(\"Setting ihashcode of an object whose ihashcode is already initialized.\");\n        }\n    }\n\n    private static void checkIsSupported() {\n        if (!Continuation.isSupported()) {\n            throw new UnsupportedOperationException(\"This VM does not support identity hashcode preservation.\");\n        }\n    }\n\n    private static native boolean isInitialized0(Object o);\n\n    private static native boolean setIHashcode0(Object o, int hashcode);\n\n    private IdentityHashCodes() {\n    }\n}\n","sourceCodeStart":77,"sourceCodeEnd":112,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/espresso/src/org.graalvm.continuations/src/org/graalvm/continuations/IdentityHashCodes.java#L77-L112","documentation":"IllegalStateException from IdentityHashCodes.set: the object's identity hashcode was already initialized, so it cannot be reassigned. An identity hashcode gets initialized by Object.hashCode resolving to Object.hashCode, by System.identityHashCode(o), or by a previous successful set/trySet — after that the value is fixed for the object's lifetime, which is exactly why set() refuses to overwrite it. This API exists so continuation deserialization can restore recorded identity hashcodes; overwriting would break hash-table invariants.","triggerScenarios":"Calling IdentityHashCodes.set(o, h) after o.hashCode() or System.identityHashCode(o) was already called on the object, or after a prior set/trySet on it; typical during deserialization when framework code hashes the object before restoring its hashcode.","commonSituations":"A deserializer that puts freshly allocated objects into a HashMap (initializing their identity hashcodes) before calling set; logging or caching code touching hashCode during reconstruction; restoring the same object graph twice.","solutions":["Use IdentityHashCodes.trySet(o, h) (returns false instead of throwing) when a pre-initialized hashcode is tolerable.","Guard with IdentityHashCodes.has(o) before calling set.","Call set() as early as possible on freshly allocated objects, before anything can hash them.","If the original hashcode matters for correctness (objects live in hash structures keyed by identity), redo the restoration pass before inserting into any HashMap/HashSet."],"exampleFix":"// before\nmap.put(o, k);            // initializes identity hashcode\nIdentityHashCodes.set(o, recordedHash); // throws IllegalStateException\n\n// after\nif (!IdentityHashCodes.has(o)) {\n    IdentityHashCodes.trySet(o, recordedHash);\n}\nmap.put(o, k); // hash after restore","handlingStrategy":"validation","validationCode":"// before set: check initialization state (requires continuation-capable VM)\nif (Continuation.isSupported() && !IdentityHashCodes.has(o)) {\n    IdentityHashCodes.set(o, recordedHash);\n}","typeGuard":null,"tryCatchPattern":"try { IdentityHashCodes.set(o, hash); } catch (IllegalStateException e) { /* hashcode already fixed; accept existing value or fail restoration */ }","preventionTips":["Prefer trySet(o, hash) and treat false as 'already initialized, skip'.","Restore identity hashcodes before the object is inserted into any HashMap/HashSet or logged with hashCode.","Never hash a freshly deserialized object before running the hashcode-restoration pass."],"tags":["continuations","identity-hashcode","serialization","deserialization"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}