Tencent/APIJSON · error · IllegalArgumentException
HEAD请求: 字符{origin} 不合法!预编译模式下 @column:value 中 value里面用 , 分割的
Error message
HEAD请求: 字符{origin} 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项 column:alias 中 column 必须是1个单词!如果有alias,则 alias 也必须为1个单词!并且不要有多余的空格! What it means
Thrown in the HEAD/HEADS branch of gainColumnString when, in prepared mode, the column part (text before the last ':') of an @column item fails StringUtil.isName and also does not look like a function call — there is no '(' or the ')' does not come after it. The library only accepts a plain identifier or a function(arg,...) form inside HEAD @column, so anything else is rejected as a potential injection vector.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java:2330
//column.remove(c);
continue;
}
}
int index = c.lastIndexOf(":"); //StringUtil.split返回数组中,子项不会有null
String origin = index < 0 ? c : c.substring(0, index);
String alias = index < 0 ? null : c.substring(index + 1);
if (alias != null && StringUtil.isName(alias) == false) {
throw new IllegalArgumentException("HEAD请求: 字符 " + alias
+ " 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项"
+ " column:alias 中 column 必须是1个单词!如果有alias,则alias也必须为1个单词!并且不要有多余的空格!");
}
if (StringUtil.isName(origin) == false) {
int start = origin.indexOf("(");
if (start < 0 || origin.lastIndexOf(")") <= start) {
throw new IllegalArgumentException("HEAD请求: 字符" + origin
+ " 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项"
+ " column:alias 中 column 必须是1个单词!"
+ "如果有alias,则 alias 也必须为1个单词!并且不要有多余的空格!");
}
if (start > 0 && StringUtil.isName(origin.substring(0, start)) == false) {
throw new IllegalArgumentException("HEAD请求: 字符 " + origin.substring(0, start)
+ " 不合法!预编译模式下 @column:value 中 value里面用 , 分割的每一项"
+ " column:alias 中 column 必须是1个单词!如果有alias,则alias也必须为1个单词!并且不要有多余的空格!");
}
}
}
}
boolean onlyOne = column != null && column.size() == 1;
String c0 = onlyOne ? column.get(0) : null;
if (onlyOne) {View on GitHub (pinned to 5284052872)
Solutions
- Use a single column name: "@column":"id".
- If a function is used, use the exact form fun(arg) with balanced parentheses, e.g. "@column":"max(id)".
- Drop @column to get count(*).
- For qualified or complex expressions, configure them as server-side @raw entries so the prepared-mode parser skips them.
Example fix
// before
{"User":{"@column":"sum(id+1"}}
// after
{"User":{"@column":"sum(id)"}} Defensive patterns
Strategy: validation
Validate before calling
const valid = /^[A-Za-z][A-Za-z0-9_]*(\([^()]*\))?$/.test(item);
if (!valid) throw new Error('HEAD @column must be a word or fn(args)'); Type guard
null
Try / catch
catch IllegalArgumentException, map to 400, echo the accepted syntax to the caller
Prevention
- Only single column names or fn(arg) forms in HEAD @column
- Client-side paren balance check before send
- No dotted or computed columns in count requests
When it happens
Trigger: HEAD request with "@column":"count(id" (unbalanced parentheses), "@column":"id+1" (expression without parens), or "@column":"user.id" (dotted name is not a single word and has no function parens).
Common situations: Trying to count on a computed expression or a joined-table qualified column in a HEAD request; porting a GET query with complex @column to HEAD without simplifying; typo'd parentheses when hand-writing a function.
Related errors
- HEAD请求: 字符 {alias} 不合法!预编译模式下 @column:value 中 value里面用 , 分割的
- HEAD请求: 字符 {origin.substring(0, start)} 不合法!预编译模式下 @column:v
- POST 请求必须在Table内设置要保存的 key:value !
- POST请求: 每一个 key:value 中的key都必须是1个单词!
- @column:value 的 value 中字符串 {expression} 不合法!不允许传超过 100 个字符的函
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/ef996cf66a88306f.
Report an issue: GitHub.