{"record":{"id":"906ba8b7cbfe4bdc","repo":"hibernate/hibernate-orm","slug":"could-not-find-cte-for-name-ctename","errorCode":null,"errorMessage":"Could not find CTE for name '\" + cteName + \"'!","messagePattern":"Could not find CTE for name '\" \\+ cteName \\+ \"'!","errorType":"exception","errorClass":"InterpretationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/sql/spi/BaseSqmToSqlAstConverter.java","lineNumber":3214,"sourceCode":"\t\t\tinNestedContext = oldInNestedContext;\n\t\t\tif ( !lateral ) {\n\t\t\t\tfromClauseIndexStack.pop();\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate TableGroup createCteTableGroup(\n\t\t\tString cteName,\n\t\t\tNavigablePath navigablePath,\n\t\t\tString explicitAlias,\n\t\t\tboolean canUseInnerJoins) {\n\t\tfinal var sqlAliasBase = getSqlAliasBaseGenerator().createSqlAliasBase(\n\t\t\t\texplicitAlias == null ? cteName : explicitAlias\n\t\t);\n\t\tfinal String identifierVariable = sqlAliasBase.generateNewAlias();\n\t\tfinal var cteStatement = cteContainer.getCteStatement( cteName );\n\t\tif ( cteStatement == null ) {\n\t\t\tthrow new InterpretationException( \"Could not find CTE for name '\" + cteName + \"'!\" );\n\t\t}\n\t\tfinal var cteQueryPart = ( (SelectStatement) cteStatement.getCteDefinition() ).getQueryPart();\n\t\t// If the query part of the CTE is one which we are currently processing, then this is a recursive CTE\n\t\tif ( cteQueryPart instanceof QueryGroup && TRUE == processingStateStack.findCurrentFirstWithParameter( cteQueryPart, BaseSqmToSqlAstConverter::matchSqlAstWithQueryPart ) ) {\n\t\t\tcteStatement.setRecursive();\n\t\t}\n\t\tfinal var tableGroupProducer = cteStatement.getCteTable().getTableGroupProducer();\n\t\treturn new CteTableGroup(\n\t\t\t\tcanUseInnerJoins,\n\t\t\t\tnavigablePath,\n\t\t\t\tsqlAliasBase,\n\t\t\t\ttableGroupProducer,\n\t\t\t\tnew NamedTableReference( cteName, identifierVariable ),\n\t\t\t\ttableGroupProducer.getCompatibleTableExpressions()\n\t\t);\n\t}\n\n\tprivate void consumeJoins(SqmRoot<?> sqmRoot, FromClauseIndex fromClauseIndex, TableGroup tableGroup) {","sourceCodeStart":3196,"sourceCodeEnd":3232,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/spi/BaseSqmToSqlAstConverter.java#L3196-L3232","documentation":"Thrown when createCteTableGroup() builds the table group for a reference to a CTE and cteContainer.getCteStatement(cteName) returns null. The statement being translated refers to a CTE label that is registered neither in the current CTE scope nor in any parent scope, so there is no definition to read the table group producer from.","triggerScenarios":"HQL 'with x as (...) select ... from y' where the from-clause name y is a typo for x; referencing a CTE that is declared inside a nested subquery from the outer statement (out of scope); case or quoting mismatches between the with-clause label and the reference (backticked vs plain name).","commonSituations":"Hand-written HQL with with-clauses where label and usage drift apart; refactoring that renames a CTE in the with-clause but not in the from-clause; queries assembled from string fragments; criteria code that consumes a CTE before adding its statement to the container.","solutions":["Make the referenced name exactly match the with-clause label, including case and any backtick quoting","Declare the CTE at the statement level that actually references it, not inside a deeper subquery","If building the query programmatically, add the CteStatement to the SqmCteContainer before any reference is translated","Verify the dialect supports CTEs at all; unsupported dialects can drop statements from the container"],"exampleFix":"// before\nwith totals as (select p.id, sum(o.amt) t from ...)\nselect * from total s\n\n// after\nwith totals as (select p.id, sum(o.amt) t from ...)\nselect * from totals","handlingStrategy":"try-catch","validationCode":"// For programmatically built queries: verify each referenced CTE is declared in scope\nSet<String> declared = cteContainer.getCteStatements().stream()\n    .map(s -> s.getCteTable().getCteName())\n    .collect(java.util.stream.Collectors.toSet());\nif (!declared.contains(referenceName)) {\n    throw new IllegalStateException(\"CTE '\" + referenceName + \"' referenced but not declared: \" + declared);\n}","typeGuard":null,"tryCatchPattern":"try {\n    return session.createQuery(hql).getResultList();\n} catch (org.hibernate.query.sqm.InterpretationException e) {\n    log.error(\"CTE reference failed; with-clause labels in query: {}\", extractWithLabels(hql), e);\n    throw e;\n}","preventionTips":["Define CTE label constants and use them in both the with-clause and from-clause","Declare CTEs at the top statement level, never inside a subquery that others reference","Unit-test every HQL with a with-clause against a real SessionFactory in CI"],"tags":["hibernate","hql","cte","unknown-reference","query-translation"],"backgroundTag":"unknown-cte-reference","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}