{"record":{"id":"81f3614a42bdd425","repo":"hibernate/hibernate-orm","slug":"json-path-jsonpath-uses-parameter-parametern","errorCode":null,"errorMessage":"JSON path [{jsonPath}] uses parameter [{parameterName}] that is not passed","messagePattern":"JSON path \\[(.+?)\\] uses parameter \\[(.+?)\\] that is not passed","errorType":"exception","errorClass":"QueryException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/dialect/function/json/H2JsonValueFunction.java","lineNumber":145,"sourceCode":"\t\tjsonDocument.accept( walker );\n\t\tif ( needsWrapping ) {\n\t\t\tif ( !isJson ) {\n\t\t\t\tsqlAppender.append( \" format json\" );\n\t\t\t}\n\t\t\tsqlAppender.appendSql( ')' );\n\t\t}\n\t\tfor ( int i = 0; i < jsonPathElements.size(); i++ ) {\n\t\t\tfinal JsonPathHelper.JsonPathElement jsonPathElement = jsonPathElements.get( i );\n\t\t\tif ( jsonPathElement instanceof JsonPathHelper.JsonAttribute attribute ) {\n\t\t\t\tsqlAppender.appendSql( \".\" );\n\t\t\t\tsqlAppender.appendDoubleQuoteEscapedString( attribute.attribute() );\n\t\t\t}\n\t\t\telse if ( jsonPathElement instanceof JsonPathHelper.JsonParameterIndexAccess parameterIndexAccess ) {\n\t\t\t\tassert passingClause != null;\n\t\t\t\tfinal String parameterName = parameterIndexAccess.parameterName();\n\t\t\t\tfinal Expression expression = passingClause.getPassingExpressions().get( parameterName );\n\t\t\t\tif ( expression == null ) {\n\t\t\t\t\tthrow new QueryException( \"JSON path [\" + jsonPath + \"] uses parameter [\" + parameterName + \"] that is not passed\" );\n\t\t\t\t}\n\n\t\t\t\tsqlAppender.appendSql( '[' );\n\t\t\t\texpression.accept( walker );\n\t\t\t\tsqlAppender.appendSql( \"+1]\" );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsqlAppender.appendSql( '[' );\n\t\t\t\tsqlAppender.appendSql( ( (JsonPathHelper.JsonIndexAccess) jsonPathElement ).index() + 1 );\n\t\t\t\tsqlAppender.appendSql( ']' );\n\t\t\t}\n\t\t}\n\t}\n\n\tstatic String applyJsonPath(String parentPath, boolean isColumn, boolean isJson, String jsonPath, @Nullable JsonPathPassingClause passingClause) {\n\t\tif ( \"$\".equals( jsonPath ) ) {\n\t\t\treturn parentPath;\n\t\t}","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/dialect/function/json/H2JsonValueFunction.java#L127-L163","documentation":"When H2 emulation renders a json_value JSON path, a bracket segment written as [$name] refers to a parameter from the PASSING clause. The code looks up the name in passingClause.getPassingExpressions(). If no passing expression was registered under that name, this QueryException is thrown during SQL rendering.","triggerScenarios":"A query uses json_value(doc, '$.items[$idx]') but has no PASSING clause, or the passing clause registers a different name, for example PASSING :x AS other. The lookup returns null and the error names the missing parameter.","commonSituations":"Typos between the $name inside the path and the AS alias in the PASSING clause. Queries ported from a database where the path used positional indexes. Dynamic path strings assembled at runtime that reference parameters never declared in the query.","solutions":["Add a passing entry whose alias matches the path parameter: json_value(doc, '$.items[$idx]' PASSING :i AS idx).","Check the spelling: the name after $ in the path must equal the alias after AS character for character.","Replace the parameter access with a literal index: '$.items[0]'.","If the parameter is intentional, verify the HQL parser kept the PASSING clause and that it was not dropped by query rewriting."],"exampleFix":"// before\nselect json_value(e.doc, '$.items[$idx]') from Entity e\n\n// after\nselect json_value(e.doc, '$.items[$idx]' passing :i as idx) from Entity e","handlingStrategy":"validation","validationCode":"// Extract $names from the path and compare with the aliases you bind.\nstatic Set<String> pathParams(String path) {\n    var names = new java.util.HashSet<String>();\n    var m = java.util.regex.Pattern.compile(\"\\\\[\\\\$(\\\\w+)\\\\]\").matcher(path);\n    while (m.find()) names.add(m.group(1));\n    return names;\n}\nstatic void checkPassing(String path, Map<String, Object> passing) {\n    for (String name : pathParams(path)) {\n        if (!passing.containsKey(name))\n            throw new IllegalArgumentException(\"Path uses unbound parameter: $\" + name);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return session.createQuery(hql, String.class).getResultList();\n} catch (org.hibernate.QueryException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"that is not passed\")) {\n        // Log path and aliases, then fix the PASSING clause.\n        throw new IllegalArgumentException(\"JSON path parameter not passed: \" + e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Define path constants and their passing aliases together in one class.","Unit-test that every $name in a path constant has a matching binding.","Use identical alias and parameter names to avoid mismatches."],"tags":["hibernate","h2","json","json-path","passing-clause","parameter-mismatch"],"backgroundTag":"json-path-parameter-not-passed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}