{"record":{"id":"305754aba9507b3a","repo":"hibernate/hibernate-orm","slug":"no-object-key-available","errorCode":null,"errorMessage":"no object key available","messagePattern":"no object key available","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/format/OsonDocumentReader.java","lineNumber":109,"sourceCode":"\t\t\t\treturn JsonDocumentItemType.VALUE;\n\t\t\tcase VALUE_DOUBLE:\n\t\t\t\tcurrentValue = this.parser.getDouble();\n\t\t\t\treturn JsonDocumentItemType.VALUE;\n\t\t\tcase VALUE_FLOAT:\n\t\t\t\tcurrentValue = this.parser.getFloat();\n\t\t\t\treturn JsonDocumentItemType.VALUE;\n\t\t\tcase VALUE_BINARY:\n\t\t\t\tcurrentValue = this.parser.getBytes();\n\t\t\t\treturn JsonDocumentItemType.VALUE;\n\t\t\tdefault :\n\t\t\t\tthrow new IllegalStateException( \"Unknown OSON event: \" + evt );\n\t\t}\n\t}\n\n\t@Override\n\tpublic String getObjectKeyName() {\n\t\tif (currentKeyName == null)\n\t\t\tthrow new IllegalStateException(\"no object key available\");\n\t\treturn currentKeyName;\n\t}\n\n\t@Override\n\tpublic String getStringValue() {\n\t\treturn (String)currentValue;\n\t}\n\n\t@Override\n\tpublic BigDecimal getBigDecimalValue() {\n\t\treturn (BigDecimal)currentValue;\n\t}\n\n\t@Override\n\tpublic BigInteger getBigIntegerValue() {\n\t\treturn ((BigDecimal)currentValue).toBigInteger();\n\t}\n","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/format/OsonDocumentReader.java#L91-L127","documentation":"OsonDocumentReader.getObjectKeyName() returns the current key name only right after the parser produced a KEY_NAME event (mapped to JsonDocumentItemType.VALUE_KEY): next() resets currentKeyName to null and only the KEY_NAME branch sets it. Calling the accessor at any other position in the iteration throws IllegalStateException 'no object key available'.","triggerScenarios":"Calling getObjectKeyName() when the last next() returned anything other than the key item type - e.g. while iterating array elements, before the first next(), or after consuming the key and its value.","commonSituations":"Custom adapters or integration code driving JsonDocumentReader; porting Jackson-style code where field names are always available; test harnesses that call accessors eagerly.","solutions":["Only call getObjectKeyName() immediately after next() returned the object-key item type","Track the last returned JsonDocumentItemType in your loop and gate key/value accessors on it","Read payloads via the typed getters (getStringValue/getBigDecimalValue/...) only after VALUE items"],"exampleFix":"// before\nreader.next();\nString key = reader.getObjectKeyName(); // throws if last item was not a key\n\n// after\nif (reader.next() == JsonDocumentItemType.VALUE_KEY) {\n    String key = reader.getObjectKeyName();\n}","handlingStrategy":"validation","validationCode":"JsonDocumentItemType last = null;\nwhile (reader.hasNext()) {\n    last = reader.next();\n    if (last == JsonDocumentItemType.VALUE_KEY) {\n        String key = reader.getObjectKeyName(); // only valid here\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Read the interface contract: accessors are valid only immediately after the matching next()","Gate every typed accessor on the last returned JsonDocumentItemType","Centralize reader traversal in one adapter class instead of sprinkling next()/getObjectKeyName() calls"],"tags":["hibernate","oracle","oson","json","document-reader","state-machine"],"backgroundTag":"json-reader-state-misuse","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}