Tencent/APIJSON · error · IllegalArgumentException
{}:{ @combine:'{}' } 中字符 '{}' 不合法!非逻辑符 '!' 右边多了一个字符 '{}' !非逻
Error message
{}:{ @combine:'{}' } 中字符 '{}' 不合法!非逻辑符 '!' 右边多了一个字符 '{}' !非逻辑符 '!' 右边不允许任何相邻空格 ' ',也不允许 ')' '&' '|' 中任何一个! What it means
When '!' is in operator position (after a space or '('), the next char must be a legal operand start. If it is ')', '&' or '!' (the check literally tests next == ')' || next == '&' || next == '!'), the NOT has nothing valid to negate — e.g. "!)", "!&", "!!" — and the expression is rejected, mirroring the rule that ! must be followed directly by a key or '('.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java:3590
lastLogic = c;
i ++;
}
else {
key += c;
}
}
else if (c == '!') {
last = i <= 0 ? 0 : s.charAt(i - 1); // & | 后面跳过了空格
char next = i >= n - 1 ? 0 : s.charAt(i + 1);
if (last == ' ' || last == '(') {
if (next == ' ') {
throw new IllegalArgumentException(errPrefix + " 中字符 '" + s.substring(0, i + 1)
+ "' 不合法!非逻辑符 '!' 右边多了一个空格 ' ' !非逻辑符 '!' " +
"右边不允许任何相邻空格 ' ',也不允许 ')' '&' '|' 中任何一个!");
}
if (next == ')' || next == '&' || next == '!') {
throw new IllegalArgumentException(errPrefix + " 中字符 '" + s.substring(0, i + 1)
+ "' 不合法!非逻辑符 '!' 右边多了一个字符 '"
+ next + "' !非逻辑符 '!' 右边不允许任何相邻空格 ' ',也不允许 ')' '&' '|' 中任何一个!");
}
if (i > 0 && lastLogic <= 0 && last != '(') {
throw new IllegalArgumentException(errPrefix + " 中字符 '" + s.substring(i)
+ "' 不合法!左边缺少 & | 逻辑连接符!逻辑连接符 & | 左右必须各一个相邻空格!空格不能多也不能少!"
+ "不允许首尾有空格,也不允许连续空格!左括号 ( 的右边 和 右括号 ) 的左边 都不允许有相邻空格!");
}
}
if (next == '(') {
result += SQL.NOT;
lastLogic = c;
}
else if (last <= 0 || last == ' ' || last == '(') {
isNot = true;
// lastLogic = c;
}View on GitHub (pinned to 5284052872)
Solutions
- Use a single '!' directly before a key or group: "!name", "!(a | b)".
- Remove stray '!' characters; double negation is not supported — express it by restructuring the logic.
- Check the char immediately after every '!' before sending (see validation code).
Example fix
// before
{"@combine":"a & !!b"}
// after
{"@combine":"a & b"} Defensive patterns
Strategy: validation
Validate before calling
for (int i = 0; i < combine.length(); i++) {
if (combine.charAt(i) == '!' && i + 1 < combine.length()) {
char next = combine.charAt(i + 1);
if (next == ')' || next == '&' || next == '!' || next == ' ')
throw new IllegalArgumentException("invalid char after '!': " + next);
}
} Type guard
function validNotFollow(s: string): boolean {
for (let i = 0; i < s.length; i++) {
if (s[i] === '!' && i + 1 < s.length) {
const n = s[i + 1];
if (n === ')' || n === '&' || n === '!' || n === ' ') return false;
}
}
return true;
} Prevention
- One '!' only; restructure logic instead of double negation.
- Ensure ')' '&' '!' never immediately follow '!'.
- Watch for keyboard typos ('!' where '1' meant).
When it happens
Trigger: @combine:"id & !)name", "!( & a)", "a & !!b" (double negation written as '!!' rather than applying ! once), or trailing "!" at a boundary adjacent to ')'. Trigger at line 3590. Note the message's listed forbidden set includes ')' '&' '|' but the code tests ')' '&' '!' — the message text is slightly inaccurate; the real test is those three chars.
Common situations: Typos (shift held too long producing '!' instead of '1'); attempting double negation '!!key'; copy-paste mangling parentheses next to NOT.
Related errors
- {}:{ @combine:'{}' } 中字符 '{}' 不合法!非逻辑符 '!' 右边多了一个空格 ' ' !非逻辑
- {}:{ @combine:'{}' } 中字符 '{}' 不合法!左边缺少 & | 逻辑连接符!逻辑连接符 & | 左
- {errPrefix} 中字符 '{s}' 不合法!空格 ' ' 左边缺少条件 key !逻辑连接符 & | 左右必须各
- {errPrefix} 中字符 '{key}' 不合法!左边缺少 & | 其中一个逻辑连接符!
- {}:{ @combine:'{}' } 中字符 '{}' 不合法!逻辑连接符 & 右边缺少一个空格 !逻辑连接符 &
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/a64f0dce76321bdc.
Report an issue: GitHub.