{"record":{"id":"bcf4438e21090719","repo":"Tencent/APIJSON","slug":"combine-bcf443","errorCode":null,"errorMessage":"{}:{ @combine: '{}' } 中字符 '{}' 不合法！逻辑连接符 | 右边缺少一个空格 ！逻辑连接符 & | 左右必须各一个相邻空格！空格不能多也不能少！不允许首尾有空格，也不允许连续空格！左括号 ( 右边和右括号 ) 左边都不允许有相邻空格！","messagePattern":"(.+?):(.+?)' \\} 中字符 '(.+?)' 不合法！逻辑连接符 \\| 右边缺少一个空格 ！逻辑连接符 & \\| 左右必须各一个相邻空格！空格不能多也不能少！不允许首尾有空格，也不允许连续空格！左括号 \\( 右边和右括号 \\) 左边都不允许有相邻空格！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java","lineNumber":3565,"sourceCode":"\t\t\t\t\tif (last == ' ') {\n\t\t\t\t\t\tif (i >= n - 1 || s.charAt(i + 1) != ' ') {\n\t\t\t\t\t\t\tthrow new IllegalArgumentException(errPrefix + \" 中字符 '\" + (i >= n - 1 ? s : s.substring(0, i + 1))\n\t\t\t\t\t\t\t\t\t+ \"' 不合法！逻辑连接符 & 右边缺少一个空格 ！逻辑连接符 & | 左右必须各一个相邻空格！空格不能多也不能少！\"\n\t\t\t\t\t\t\t\t\t+ \"不允许首尾有空格，也不允许连续空格！左括号 ( 的右边 和 右括号 ) 的左边 都不允许有相邻空格！\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresult += SQL.AND;\n\t\t\t\t\t\tlastLogic = c;\n\t\t\t\t\t\ti ++;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tkey += c;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (c == '|') {\n\t\t\t\t\tif (last == ' ') {\n\t\t\t\t\t\tif (i >= n - 1 || s.charAt(i + 1) != ' ') {\n\t\t\t\t\t\t\tthrow new IllegalArgumentException(table + \":{ @combine: '\" + combine\n\t\t\t\t\t\t\t\t\t+ \"' } 中字符 '\" + (i >= n - 1 ? s : s.substring(0, i + 1))\n\t\t\t\t\t\t\t\t\t+ \"' 不合法！逻辑连接符 | 右边缺少一个空格 ！逻辑连接符 & | 左右必须各一个相邻空格！空格不能多也不能少！\"\n\t\t\t\t\t\t\t\t\t+ \"不允许首尾有空格，也不允许连续空格！左括号 ( 右边和右括号 ) 左边都不允许有相邻空格！\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresult += SQL.OR;\n\t\t\t\t\t\tlastLogic = c;\n\t\t\t\t\t\ti ++;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tkey += c;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (c == '!') {\n\t\t\t\t\tlast = i <= 0 ? 0 : s.charAt(i - 1);  // & | 后面跳过了空格\n\n\t\t\t\t\tchar next = i >= n - 1 ? 0 : s.charAt(i + 1);\n\t\t\t\t\tif (last == ' ' || last == '(') {","sourceCodeStart":3547,"sourceCodeEnd":3583,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L3547-L3583","documentation":"Identical rule to error 155 but for '|': when '|' follows a leading space (operator position) but is not followed by exactly one space — next char is not ' ' or the operator is at end of string — the expression violates the single-space-around-operator grammar and is rejected.","triggerScenarios":"@combine:\"id |name\", \"id |\", \"(a|b)\" won't reach here (no spaces) but \"a |(b)\" will: after '|' comes '(' not ' '. Trigger at line 3565. Note this error's message uses table+combine directly rather than errPrefix, but the meaning is the same.","commonSituations":"Same as 155: single-sided spacing around OR operators; \"a |(b | c)\" style grouping where '(' directly follows the operator.","solutions":["Write ' | ' with exactly one space on each side: \"a | (b | c)\".","Use the programmatic join helper / pre-validation regex before sending.","Never place '(' immediately after '&' or ')' immediately before them — spaces around operators only, none adjacent to parentheses."],"exampleFix":"// before\n{\"@combine\":\"id |(name | tag)\"}\n// after\n{\"@combine\":\"id | (name | tag)\"}","handlingStrategy":"validation","validationCode":"// same grammar as '&' — one space on both sides of '|'\nif (!combine.matches(\"(\\\\S+|\\\\([^()]*\\\\))(\\\\s[&|]\\\\s(\\\\S+|\\\\([^()]*\\\\)))*\"))\n    throw new IllegalArgumentException(\"@combine must use exactly one space around each & and |\");","typeGuard":"function isWellSpaced(combine: string): boolean {\n  return /^(?:\\S+|\\([^()]*\\))(?:\\s[&|]\\s(?:\\S+|\\([^()]*\\)))*$/.test(combine);\n}","tryCatchPattern":null,"preventionTips":["Write ' | (b | c)' — space after |, space before (, but no space between ( and its operand.","Use the same join helper for & and |.","Add unit fixtures for OR chains in generated expressions."],"tags":["apijson","combine","whitespace","syntax-error"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}