{"record":{"id":"62289e6ce3ee809c","repo":"hibernate/hibernate-orm","slug":"json-path-expression-expression-emulation-only-sup","errorCode":null,"errorMessage":"Json path expression expression emulation only supports absolute paths i.e. must start with a '$' but got: {jsonPath}","messagePattern":"Json path expression expression emulation only supports absolute paths i\\.e\\. must start with a '\\$' but got: (.+?)","errorType":"exception","errorClass":"QueryException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/dialect/function/json/JsonPathHelper.java","lineNumber":21,"sourceCode":" * Copyright Red Hat Inc. and Hibernate Authors\n */\npackage org.hibernate.dialect.function.json;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.hibernate.QueryException;\nimport org.hibernate.sql.ast.SqlAstTranslator;\nimport org.hibernate.sql.ast.spi.SqlAppender;\nimport org.hibernate.sql.ast.tree.expression.Expression;\nimport org.hibernate.sql.ast.tree.expression.JsonPathPassingClause;\n\npublic class JsonPathHelper {\n\n\tpublic static List<JsonPathElement> parseJsonPathElements(String jsonPath) {\n\t\tif ( jsonPath.charAt( 0 ) != '$' ) {\n\t\t\tthrow new QueryException( \"Json path expression expression emulation only supports absolute paths i.e. must start with a '$' but got: \" + jsonPath );\n\t\t}\n\t\tfinal var jsonPathElements = new ArrayList<JsonPathElement>();\n\t\tint startIndex;\n\t\tint dotIndex;\n\n\t\tif ( jsonPath.length() > 1 ) {\n\t\t\tif ( jsonPath.charAt( 1 ) == '.' ) {\n\t\t\t\tstartIndex = 2;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfinal int bracketEndIndex = jsonPath.indexOf( ']' );\n\t\t\t\tparseBracket( jsonPath, 1, bracketEndIndex, jsonPathElements );\n\t\t\t\tstartIndex = bracketEndIndex + 2;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\twhile ( ( dotIndex = jsonPath.indexOf( '.', startIndex ) ) != -1 ) {\n\t\t\t\t\tparseAttribute( jsonPath, startIndex, dotIndex, jsonPathElements );","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/dialect/function/json/JsonPathHelper.java#L3-L39","documentation":"Hibernate JSON path emulation only accepts absolute paths. parseJsonPathElements checks the first character and requires '$'. Any path starting with something else, for example 'name' or '.name', throws this QueryException during SQL rendering.","triggerScenarios":"A json_value, json_query, or json_exists call passes a path without the root sign: json_value(doc, 'customer.name'). The charAt(0) check fails and the error includes the offending path.","commonSituations":"Paths copied from JavaScript or MongoDB style access. User input used for the path without normalization. Migrating raw SQL where the database accepted lax paths.","solutions":["Prefix the path with the root: use '$.customer.name'.","Normalize user-supplied paths once at the application boundary: prepend '$' and '.' when missing.","Use the strict root form even for single segments: '$.name', not 'name'."],"exampleFix":"// before\nselect json_value(e.doc, 'customer.name') from Entity e\n\n// after\nselect json_value(e.doc, '$.customer.name') from Entity e","handlingStrategy":"validation","validationCode":"static String normalizeJsonPath(String path) {\n    if (path == null || path.isBlank()) {\n        throw new IllegalArgumentException(\"JSON path is empty\");\n    }\n    if (path.charAt(0) != '$') {\n        path = \"$\" + (path.charAt(0) == '.' ? \"\" : \".\") + path;\n    }\n    return path;\n}\nString safe = normalizeJsonPath(userInput); // 'customer.name' -> '$.customer.name'","typeGuard":"static boolean isAbsoluteJsonPath(String path) {\n    return path != null && !path.isEmpty() && path.charAt(0) == '$';\n}","tryCatchPattern":"try {\n    return session.createQuery(hql, String.class).getSingleResult();\n} catch (org.hibernate.QueryException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"must start with a '$'\")) {\n        throw new IllegalArgumentException(\"Reject or normalize the supplied JSON path\", e);\n    }\n    throw e;\n}","preventionTips":["Normalize every external JSON path through one helper before it reaches a query.","Reject paths that lack the root sign at the API boundary.","Document the '$.attr' form in your API contract."],"tags":["hibernate","json","json-path","path-validation"],"backgroundTag":"json-path-must-be-absolute","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}