hibernate/hibernate-orm · error · QueryException

JSON path [" + JsonPathHelper.toJsonPath( jsonPathElements )

Error message

JSON path [" + JsonPathHelper.toJsonPath( jsonPathElements ) + "] uses parameter [" + parameterName + "] that is not passed

What it means

When the CockroachDB json_value() emulation rewrites a literal JSON path, $name tokens inside the path (parameter index access such as $.items[$i]) are resolved against the query's PASSING clause bindings. If a name referenced by the path has no matching passing expression - jsonPathPassingClause.getPassingExpressions().get(name) returns null - rendering aborts with this QueryException.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/dialect/function/json/CockroachDBJsonValueFunction.java:102

			sqlAppender.appendSql( " as jsonb)" );
		}
		else {
			sqlAppender.appendSql( ')' );
		}
		sqlAppender.appendSql( "#>>array" );
		char separator = '[';
		final Dialect dialect = walker.getSessionFactory().getJdbcServices().getDialect();
		for ( JsonPathHelper.JsonPathElement jsonPathElement : jsonPathElements ) {
			sqlAppender.appendSql( separator );
			if ( jsonPathElement instanceof JsonPathHelper.JsonAttribute attribute ) {
				dialect.appendLiteral( sqlAppender, attribute.attribute() );
			}
			else if ( jsonPathElement instanceof JsonPathHelper.JsonParameterIndexAccess ) {
				assert jsonPathPassingClause != null;
				final String parameterName = ( (JsonPathHelper.JsonParameterIndexAccess) jsonPathElement ).parameterName();
				final Expression expression = jsonPathPassingClause.getPassingExpressions().get( parameterName );
				if ( expression == null ) {
					throw new QueryException( "JSON path [" + JsonPathHelper.toJsonPath( jsonPathElements ) + "] uses parameter [" + parameterName + "] that is not passed" );
				}

				sqlAppender.appendSql( "cast(" );
				expression.accept( walker );
				sqlAppender.appendSql( " as text)" );
			}
			else {
				sqlAppender.appendSql( '\'' );
				sqlAppender.appendSql( ( (JsonPathHelper.JsonIndexAccess) jsonPathElement ).index() );
				sqlAppender.appendSql( '\'' );
			}
			separator = ',';
		}
		if ( jsonPathElements.isEmpty() ) {
			sqlAppender.appendSql( '[' );
		}
		sqlAppender.appendSql( ']' );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add the missing binding: json_value(d.doc, '$.tags[$i]' passing :idx as i)
  2. Make the names match exactly - the token inside $[...] must equal the AS alias in the PASSING clause, case-sensitively
  3. Remove the parameter token from the path if it was accidental and use a literal index
  4. Add a unit test that extracts $tokens from your paths and asserts each has a PASSING alias

Example fix

// before - path uses $i but nothing is passed for it
select json_value(d.doc, '$.tags[$i]') from Document d

// after - bind i through the passing clause
select json_value(d.doc, '$.tags[$i]' passing :idx as i) from Document d
Defensive patterns

Strategy: validation

Validate before calling

// Every $name token inside a literal path must have a matching PASSING alias
static void assertPassingBindings(String literalPath, java.util.Set<String> passingAliases) {
    java.util.regex.Matcher m = java.util.regex.Pattern.compile("\\$([A-Za-z_]\\w*)").matcher(literalPath);
    while (m.find()) {
        if (!passingAliases.contains(m.group(1))) {
            throw new IllegalArgumentException(
                "JSON path parameter '" + m.group(1) + "' is not bound by a PASSING clause");
        }
    }
}

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")) {
        throw new IllegalArgumentException(
            "Path references a parameter missing from the PASSING clause; check aliases (case-sensitive)", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: A literal path that references a parameter which is never bound, or is bound under a different name: select json_value(d.doc, '$.tags[$i]') from Document d with no passing clause, or json_value(d.doc, '$.tags[$i]' passing :idx as index) where the path uses 'i' but the alias defined is 'index'.

Common situations: Renaming a bind alias without updating the path string; case mismatches between the path token and the AS alias (matching is case-sensitive); copy-pasting a path from documentation that references parameters the query never defines.

Related errors


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