hibernate/hibernate-orm · error · QueryException

JSON path [{jsonPath}] uses parameter [{parameterName}] that

Error message

JSON path [{jsonPath}] uses parameter [{parameterName}] that is not passed

What it means

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.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/dialect/function/json/H2JsonValueFunction.java:145

		jsonDocument.accept( walker );
		if ( needsWrapping ) {
			if ( !isJson ) {
				sqlAppender.append( " format json" );
			}
			sqlAppender.appendSql( ')' );
		}
		for ( int i = 0; i < jsonPathElements.size(); i++ ) {
			final JsonPathHelper.JsonPathElement jsonPathElement = jsonPathElements.get( i );
			if ( jsonPathElement instanceof JsonPathHelper.JsonAttribute attribute ) {
				sqlAppender.appendSql( "." );
				sqlAppender.appendDoubleQuoteEscapedString( attribute.attribute() );
			}
			else if ( jsonPathElement instanceof JsonPathHelper.JsonParameterIndexAccess parameterIndexAccess ) {
				assert passingClause != null;
				final String parameterName = parameterIndexAccess.parameterName();
				final Expression expression = passingClause.getPassingExpressions().get( parameterName );
				if ( expression == null ) {
					throw new QueryException( "JSON path [" + jsonPath + "] uses parameter [" + parameterName + "] that is not passed" );
				}

				sqlAppender.appendSql( '[' );
				expression.accept( walker );
				sqlAppender.appendSql( "+1]" );
			}
			else {
				sqlAppender.appendSql( '[' );
				sqlAppender.appendSql( ( (JsonPathHelper.JsonIndexAccess) jsonPathElement ).index() + 1 );
				sqlAppender.appendSql( ']' );
			}
		}
	}

	static String applyJsonPath(String parentPath, boolean isColumn, boolean isJson, String jsonPath, @Nullable JsonPathPassingClause passingClause) {
		if ( "$".equals( jsonPath ) ) {
			return parentPath;
		}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add a passing entry whose alias matches the path parameter: json_value(doc, '$.items[$idx]' PASSING :i AS idx).
  2. Check the spelling: the name after $ in the path must equal the alias after AS character for character.
  3. Replace the parameter access with a literal index: '$.items[0]'.
  4. If the parameter is intentional, verify the HQL parser kept the PASSING clause and that it was not dropped by query rewriting.

Example fix

// before
select json_value(e.doc, '$.items[$idx]') from Entity e

// after
select json_value(e.doc, '$.items[$idx]' passing :i as idx) from Entity e
Defensive patterns

Strategy: validation

Validate before calling

// Extract $names from the path and compare with the aliases you bind.
static Set<String> pathParams(String path) {
    var names = new java.util.HashSet<String>();
    var m = java.util.regex.Pattern.compile("\\[\\$(\\w+)\\]").matcher(path);
    while (m.find()) names.add(m.group(1));
    return names;
}
static void checkPassing(String path, Map<String, Object> passing) {
    for (String name : pathParams(path)) {
        if (!passing.containsKey(name))
            throw new IllegalArgumentException("Path uses unbound parameter: $" + name);
    }
}

Try / catch

try {
    return session.createQuery(hql, String.class).getResultList();
} catch (org.hibernate.QueryException e) {
    if (e.getMessage() != null && e.getMessage().contains("that is not passed")) {
        // Log path and aliases, then fix the PASSING clause.
        throw new IllegalArgumentException("JSON path parameter not passed: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/81f3614a42bdd425. Report an issue: GitHub.