hibernate/hibernate-orm · error · IllegalArgumentException
Illegal cycle attribute '{}' passed, which is not part of th
Error message
Illegal cycle attribute '{}' passed, which is not part of the JpaCteCriteria! What it means
The cycle(...) overload also validates every entry of cycleAttributes against cteTable.getAttributes(); only attributes that are columns of the CTE type itself may be used for cycle detection. Passing an entity attribute from the base query (or an attribute of another CTE) throws IllegalArgumentException naming the offending attribute.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/cte/SqmCteStatement.java:322
this.cycleMarkAttributeName = null;
this.cyclePathAttributeName = null;
this.cycleValue = null;
this.noCycleValue = null;
this.cycleAttributes = Collections.emptyList();
}
else {
if ( cycleValue == null || noCycleValue == null ) {
throw new IllegalArgumentException( "Null is an illegal value for cycle mark values!" );
}
final SqmExpression<X> cycleValueLiteral = nodeBuilder().literal( cycleValue );
final SqmExpression<X> noCycleValueLiteral = nodeBuilder().literal( noCycleValue );
if ( cycleValueLiteral.getNodeType() != noCycleValueLiteral.getNodeType() ) {
throw new IllegalArgumentException( "Inconsistent types for cycle mark values: [" + cycleValueLiteral.getNodeType() + ", " + noCycleValueLiteral.getNodeType() + "]" );
}
final List<SqmCteTableColumn> attributes = new ArrayList<>( cycleAttributes.size() );
for ( JpaCteCriteriaAttribute cycleAttribute : cycleAttributes ) {
if ( !cteTable.getAttributes().contains( cycleAttribute ) ) {
throw new IllegalArgumentException(
"Illegal cycle attribute '" +
( cycleAttribute == null ? "null" : cycleAttribute.getName() ) +
"' passed, which is not part of the JpaCteCriteria!"
);
}
attributes.add( (SqmCteTableColumn) cycleAttribute );
}
this.cycleMarkAttributeName = cycleMarkAttributeName;
this.cyclePathAttributeName = cyclePathAttributeName;
this.cycleValue = (SqmLiteral<Object>) cycleValueLiteral;
this.noCycleValue = (SqmLiteral<Object>) noCycleValueLiteral;
this.cycleAttributes = attributes;
}
}
@Override
public <X> X accept(SemanticQueryWalker<X> walker) {
return walker.visitCteStatement( this );View on GitHub (pinned to fad1729dce)
Solutions
- Pass only attributes of the CTE type obtained from the JpaCteCriteria created by with(...).
- Resolve columns by name via the CTE type's getAttribute(name).
- If a needed column is missing from the CTE, select it in the CTE's base query first so it becomes a CTE attribute.
Example fix
// before cte.cycle( "isCycle", "path", true, false, List.of( personRoot.getModelfield() ) ); // entity attribute // after List<JpaCteCriteriaAttribute> cols = List.of( /* attributes of the CTE type from with(...) */ ); cte.cycle( "isCycle", "path", true, false, cols );
Defensive patterns
Strategy: validation
Validate before calling
List<JpaCteCriteriaAttribute> ok = cycleColumns.stream()
.filter( a -> cteType.getAttributes().contains( a ) )
.toList();
if ( ok.size() != cycleColumns.size() ) {
throw new IllegalArgumentException( "Some cycle columns are not CTE attributes" );
}
cte.cycle( "isCycle", "path", true, false, ok ); Type guard
static boolean isCteAttribute(JpaCteCriteriaType<?> type, JpaCteCriteriaAttribute a) {
return type.getAttributes().contains( a );
} Prevention
- Source cycle columns from the CTE type returned by with(...), never from entity metamodel attributes.
- Select the recursion column (e.g. parent id) into the CTE base query so it exists as a CTE attribute.
- Wrap CTE attribute plumbing in one helper per statement so search() and cycle() share the same attribute list.
When it happens
Trigger: cte.cycle("isCycle", "path", true, false, List.of(baseRootAttr)) where baseRootAttr is a SingularAttribute/Path of the underlying entity instead of a JpaCteCriteriaAttribute of the CTE type.
Common situations: Converting HQL 'CYCLE id SET ...' to criteria and reusing the entity metamodel attribute instead of the CTE attribute; building cycle clauses in generic helpers that receive entity attributes.
Related errors
- Null is an illegal value for cycle mark values!
- Illegal search order attribute '{}' passed, which is not par
- Inconsistent types for cycle mark values: [{}, {}]
- Illegal empty CTE name
- Illegal CTE name [%s]. Names must start with an alphabetic c
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/e4fd08de547a80b3.
Report an issue: GitHub.