{"record":{"id":"466c39c4d6b1dab3","repo":"Tencent/APIJSON","slug":"errprefix-s","errorCode":null,"errorMessage":"{errPrefix} 中字符 '{s}' 不合法！不允许首尾有空格，也不允许连续空格！空格不能多也不能少！逻辑连接符 & | 左右必须各一个相邻空格！左括号 ( 右边和右括号 ) 左边都不允许有相邻空格！","messagePattern":"(.+?) 中字符 '(.+?)' 不合法！不允许首尾有空格，也不允许连续空格！空格不能多也不能少！逻辑连接符 & \\| 左右必须各一个相邻空格！左括号 \\( 右边和右括号 \\) 左边都不允许有相邻空格！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java","lineNumber":3421,"sourceCode":"\t * @param method\n\t * @param quote\n\t * @param table\n\t * @param alias\n\t * @param conditionMap  where 或 having 对应条件的 Map\n\t * @param combine\n\t * @param verifyName\n\t * @param containRaw\n\t * @param isHaving\n\t * @return\n\t * @throws Exception\n\t */\n\tprotected String parseCombineExpression(RequestMethod method, String quote, String table, String alias\n\t\t\t, Map<String, Object> conditionMap, String combine, boolean verifyName, boolean containRaw, boolean isHaving) throws Exception {\n\n\t\tString errPrefix = table + (isHaving ? \":{ @having:{ \" : \":{ \") + \"@combine:'\" + combine + (isHaving ? \"' } }\" : \"' }\");\n\t\tString s = StringUtil.get(combine);\n\t\tif (s.startsWith(\" \") || s.endsWith(\" \") ) {\n\t\t\tthrow new IllegalArgumentException(errPrefix + \" 中字符 '\" + s\n\t\t\t\t\t+ \"' 不合法！不允许首尾有空格，也不允许连续空格！空格不能多也不能少！\"\n\t\t\t\t\t+ \"逻辑连接符 & | 左右必须各一个相邻空格！左括号 ( 右边和右括号 ) 左边都不允许有相邻空格！\");\n\t\t}\n\n\t\tif (conditionMap == null) {\n\t\t\tconditionMap = new HashMap<>();\n\t\t}\n\t\tint size = conditionMap.size();\n\n\t\tint maxCount = isHaving ? getMaxHavingCount() : getMaxWhereCount();\n\t\tif (maxCount > 0 && size > maxCount) {\n\t\t\tthrow new IllegalArgumentException(table + (isHaving ? \":{ @having:{ \" : \":{ \") + \"key0:value0, key1:value1... \" + combine\n\t\t\t\t\t+ (isHaving ? \" } }\" : \" }\") + \" 中条件 key:value 数量 \" + size + \" 已超过最大数量，必须在 0-\" + maxCount + \" 内！\");\n\t\t}\n\n\t\tString result = \"\";\n\n\t\tList<Object> preparedValues = getPreparedValueList();","sourceCodeStart":3403,"sourceCodeEnd":3439,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L3403-L3439","documentation":"parseCombineExpression() validates the @combine (or @having combine) logical expression string. The very first check rejects any value that starts or ends with a space. @combine has a strict single-space grammar: '&' and '|' must have exactly one adjacent space on each side, and no other spaces are allowed, so leading/trailing spaces always indicate a malformed expression.","triggerScenarios":"@combine:\"id & name \" or \" id|name\" — note the leading/trailing space. errPrefix shows the table and full combine value. Triggered whenever getWhereString/getHavingString parse a @combine that the caller did not trim.","commonSituations":"Building @combine by joining strings (\" \" + part + \" \"), template literals with stray whitespace, copy-paste from formatted docs. Because the grammar demands exactly one space around operators, developers often over-correct by padding the ends.","solutions":["Trim the @combine value before sending: combine.strip().","Build expressions programmatically with a helper that joins keys and operators with exactly one space and never pads the ends (see validation code).","Remember the full grammar: single spaces around & and | only; none adjacent to '(' or ')'; no doubled spaces."],"exampleFix":"// before\n{\"@combine\":\" id & name \"}\n// after\n{\"@combine\":\"id & name\"}","handlingStrategy":"validation","validationCode":"if (combine != null && (combine.startsWith(\" \") || combine.endsWith(\" \"))) {\n    throw new IllegalArgumentException(\"@combine must not start/end with a space\");\n}","typeGuard":"function isTrimmed(s: string): boolean { return s === s.trim() && !s.includes('  '); }","tryCatchPattern":null,"preventionTips":["strip() every @combine value before putting it into the request.","Build combine with join(' & ')-style helpers that never pad ends.","Ban double spaces — the grammar allows single spaces only around operators."],"tags":["apijson","combine","whitespace","expression-parsing","validation"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}