{"record":{"id":"507e0eec30eef099","repo":"hibernate/hibernate-orm","slug":"space-is-not-allowed-after-parameter-prefix","errorCode":null,"errorMessage":"Space is not allowed after parameter prefix ':'","messagePattern":"Space is not allowed after parameter prefix ':'","errorType":"exception","errorClass":"QueryParameterException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sql/internal/ParameterParser.java","lineNumber":136,"sourceCode":"\t\t\telse if ( '\\'' == c ) {\n\t\t\t\tinSingleQuotes = true;\n\t\t\t\trecognizer.other( c );\n\t\t\t}\n\t\t\t// special handling for backslash\n\t\t\telse if ( '\\\\' == c ) {\n\t\t\t\t// skip sending the backslash and instead send then next character, treating is as a literal\n\t\t\t\trecognizer.other( sqlString.charAt( ++indx ) );\n\t\t\t}\n\t\t\t// otherwise\n\t\t\telse {\n\t\t\t\tif ( c == ':' ) {\n\t\t\t\t\tif ( indx < stringLength - 1 && Character.isJavaIdentifierStart( sqlString.charAt( indx + 1 ) ) ) {\n\t\t\t\t\t\t// named parameter\n\t\t\t\t\t\tfinal int right = StringHelper.firstIndexOfChar( sqlString, HQL_SEPARATORS_BITSET, indx + 1 );\n\t\t\t\t\t\tfinal int chopLocation = right < 0 ? sqlString.length() : right;\n\t\t\t\t\t\tfinal String param = sqlString.substring( indx + 1, chopLocation );\n\t\t\t\t\t\tif ( param.isEmpty() ) {\n\t\t\t\t\t\t\tthrow new QueryParameterException(\n\t\t\t\t\t\t\t\t\t\"Space is not allowed after parameter prefix ':'\",\n\t\t\t\t\t\t\t\t\tsqlString\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\trecognizer.namedParameter( param, indx );\n\t\t\t\t\t\tindx = chopLocation - 1;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\t// For backwards compatibility, allow some known operators in the escaped form\n\t\t\t\t\t\tif ( indx < stringLength - 3\n\t\t\t\t\t\t\t\t&& sqlString.charAt( indx + 1 ) == ':'\n\t\t\t\t\t\t\t\t&& sqlString.charAt( indx + 2 ) == ':'\n\t\t\t\t\t\t\t\t&& sqlString.charAt( indx + 3 ) == ':' ) {\n\t\t\t\t\t\t\t// Detect the :: operator, escaped as ::::\n\t\t\t\t\t\t\tDeprecationLogger.DEPRECATION_LOGGER.deprecatedNativeQueryColonEscaping( \"::::\", \"::\" );\n\t\t\t\t\t\t\trecognizer.other( ':' );\n\t\t\t\t\t\t\trecognizer.other( ':' );\n\t\t\t\t\t\t\tindx += 3;","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sql/internal/ParameterParser.java#L118-L154","documentation":"While tokenizing a native SQL string, ParameterParser treats ':' followed by a Java identifier-start character as a named parameter and chops the name at the first separator (space, comma, parenthesis, etc.). If the chopped name comes out empty it throws this QueryParameterException, whose message points at the classic typo of a space between ':' and the parameter name. It is a guard against malformed named-parameter prefixes in native SQL.","triggerScenarios":"A native query string containing ': name' style typos, or a stray colon the parser cannot attribute to anything else (e.g. copy-pasted SQL with assignment-style ':=' used without the supported '::=' escape, or colons inside identifiers). Parsing happens as soon as the query is created (session.createNativeQuery / em.createNativeQuery), before execution.","commonSituations":"Hand-edited SQL templates where a space sneaks in after ':'; MySQL/PostgreSQL procedural syntax (':=') pasted into a native query — modern Hibernate passes ':=' through or expects the '::=' escape; SQL from other tools with templating colons like ':start' left in text.","solutions":["Fix the typo: remove whitespace between ':' and the parameter name (':status', not ': status').","If the colon is literal SQL (assignment, label), rewrite the SQL to avoid it or use the supported escaped form '::=' which Hibernate passes through.","Move literal text containing colons into quoted literals or bind it as a parameter value instead of inlining it.","Scan query strings for ':\\s' patterns in a build-time test over your SQL resources."],"exampleFix":"-- before\nselect * from person where status = : status\n\n-- after\nselect * from person where status = :status","handlingStrategy":"validation","validationCode":"static void validateNamedParameterSyntax(String sql) {\n    var m = java.util.regex.Pattern.compile(\":\\\\s+[A-Za-z_$]\").matcher(sql);\n    if (m.find()) throw new IllegalArgumentException(\"Whitespace after ':' at index \" + m.start() + \": '\" + sql.substring(m.start(), Math.min(sql.length(), m.start() + 10)) + \"'\");\n}","typeGuard":null,"tryCatchPattern":"try { session.createNativeQuery(sql); } catch (org.hibernate.QueryParameterException e) { /* log sql with position, fix the ':' */ throw e; }","preventionTips":["Write named parameters with no space: ':name'.","Run the validateNamedParameterSyntax check over SQL constants in unit tests.","Keep literal colons out of native SQL templates or use the documented '::=' escape for assignment operators."],"tags":["hibernate","native-query","named-parameter","query-parameter-exception","syntax"],"backgroundTag":"named-parameter-syntax-error","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}