hibernate/hibernate-orm · error · IllegalStateException

Can't pass parameter '{}', because json_table has no JSON pa

Error message

Can't pass parameter '{}', because json_table has no JSON path

What it means

In SQL/JSON, json_table's PASSING clause supplies values that placeholders inside the JSON path expression reference. SqmJsonTableFunction only tracks passing expressions when it was created with a JSON path (getArguments() lays out [document, jsonPath, null] versus [document, null]); calling passing() when columns.jsonPath is null is a modeling error, so it throws IllegalStateException.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmJsonTableFunction.java:130

	private static List<SqmTypedNode<?>> createArgumentsList(SqmExpression<?> document, @Nullable SqmExpression<String> jsonPath) {
		// Since the last argument is the Columns object, though that needs the `this` reference,
		// we need to construct an array with a null slot at the end, where the Columns instance is put into.
		// Suppress nullness checks as this will eventually turn non-nullable
		@SuppressWarnings("NullAway")
		final SqmTypedNode<?>[] array = jsonPath == null
				? new SqmTypedNode[] {document, null}
				: new SqmTypedNode[] {document, jsonPath, null};
		return Arrays.asList( array );
	}

	public Map<String, SqmExpression<?>> getPassingExpressions() {
		return passingExpressions == null ? Collections.emptyMap() : Collections.unmodifiableMap( passingExpressions );
	}

	@Override
	public JpaJsonTableFunction passing(String parameterName, Expression<?> expression) {
		if ( columns.jsonPath == null ) {
			throw new IllegalStateException( "Can't pass parameter '" + parameterName + "', because json_table has no JSON path" );
		}
		if ( passingExpressions == null ) {
			passingExpressions = new HashMap<>();
		}
		passingExpressions.put( parameterName, (SqmExpression<?>) expression );
		return this;
	}

	@Override
	public SqmJsonTableFunction<T> copy(SqmCopyContext context) {
		final var existing = context.getCopy( this );
		if ( existing != null ) {
			return existing;
		}
		final List<? extends SqmTypedNode<?>> arguments = getArguments();
		final List<SqmTypedNode<?>> argumentsCopy = new ArrayList<>( arguments.size() );
		for ( int i = 0; i < arguments.size() - 1; i++ ) {
			argumentsCopy.add( arguments.get( i ).copy( context ) );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Create the json_table function with its JSON path first, then call passing().
  2. If the query genuinely needs no path, remove the passing() call - there is nothing for the parameter to bind to.
  3. Centralize json_table construction so a pathless instance is never handed to code that calls passing().

Example fix

// before
JpaJsonTableFunction<?> t = cb.jsonTable( doc );  // no JSON path
t.passing( "minLen", cb.literal( 3 ) );           // IllegalStateException

// after
JpaJsonTableFunction<?> t = cb.jsonTable( doc, "$.items[*]?(@.len > $minLen)" );
t.passing( "minLen", cb.literal( 3 ) );
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull( jsonPath, "json_table requires a JSON path when passing() is used" );
JpaJsonTableFunction<?> t = cb.jsonTable( doc, jsonPath );
if ( passingValue != null ) {
    t.passing( "name", passingValue );
}

Prevention

When it happens

Trigger: Calling .passing(parameterName, expression) on a json_table criteria function that was built without the JSON path argument - e.g. using the pathless creation variant and then trying to parameterize the (nonexistent) path expression.

Common situations: Query-builder wrappers that optionally omit the path; refactors that dropped the path argument; xml_table-style code reused for json_table; adapting examples that always used a path to a pathless use case.

Related errors


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