Tencent/APIJSON · error · IllegalArgumentException
@group:value 中 value里面用 , 分割的每一项都必须是1个单词!并且不要有空格!
Error message
@group:value 中 value里面用 , 分割的每一项都必须是1个单词!并且不要有空格!
What it means
In prepared mode (isPrepared()), AbstractSQLConfig validates every comma-separated item of @group:value with StringUtil.isName — each must be a single identifier word. GROUP BY items cannot be bound as ? parameters, so malformed items would otherwise allow SQL injection.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java:1662
// joinGroup += (first ? "" : ", ") + c;
// first = false;
// }
//}
}
}
group = StringUtil.trim(group);
String[] keys = StringUtil.split(group);
if (keys == null || keys.length <= 0) {
return StringUtil.isEmpty(joinGroup, true) ? "" : (hasPrefix ? " GROUP BY " : "") + joinGroup;
}
for (int i = 0; i < keys.length; i++) {
if (isPrepared()) {
// 不能通过 ? 来代替,因为SQLExecutor<T, M, L> statement.setString后 GROUP BY 'userId' 有单引号,只能返回一条数据,必须去掉单引号才行!
if (StringUtil.isName(keys[i]) == false) {
throw new IllegalArgumentException("@group:value 中 value里面用 , 分割的每一项都必须是1个单词!并且不要有空格!");
}
}
keys[i] = gainKey(keys[i]);
}
return (hasPrefix ? " GROUP BY " : "") + StringUtil.concat(StringUtil.get(keys), joinGroup, ", ");
}
@Override
public String getHavingCombine() {
return havingCombine;
}
@Override
public AbstractSQLConfig<T, M, L> setHavingCombine(String havingCombine) {
this.havingCombine = havingCombine;
return this;
}View on GitHub (pinned to 5284052872)
Solutions
- Use only bare column names: "@group": "userId,date"
- Put aggregate functions in @column (e.g. "count(*):count") and group by plain columns only
- For expressions that cannot be a plain name, pre-define them in backend RAW_MAP and reference via @raw
Example fix
// before
{"@column": "count(*)", "@group": "count(*)"}
// after
{"@column": "count(*):count", "@group": "userId"} Defensive patterns
Strategy: validation
Validate before calling
const isName = s => /^[A-Za-z_][A-Za-z0-9_]*$/.test(s);
for (const item of String(obj['@group'] ?? '').split(',')) {
if (item && !isName(item.trim())) throw new Error(`@group item '${item}' must be a bare column name`);
} Type guard
const isGroupItemValid = s => /^[A-Za-z_][A-Za-z0-9_]*$/.test(s);
Try / catch
try { await api.get(req); } catch (e) { if (e.message.includes('@group')) sanitizeListField(req, '@group'); else throw e; } Prevention
- Generate @group only from a column-name picker, never free text
- Keep aggregates in @column with aliases, not in @group
When it happens
Trigger: GET request with "@group": "count(*)", "@group": "user id" (space), "@group": "userId;drop" or any item with quotes/dashes/spaces instead of a bare column name.
Common situations: Frontend passes an aggregated expression into @group instead of @column; users paste SQL fragments; column aliases with hyphens or dots.
Related errors
- 预编译模式下 @order:value 中 {item} 不合法! value 里面用 , 分割的每一项必须是 随机函数
- 字符 {ck} 不合法!预编译模式下 @column:"column0,column1:alias;function0(
- {}: { @key(): value } 对应存储过程 value 中字符 {} 不合法!schema.functio
- 字符串 ${expression} 不合法!预编译模式下 @having:"column?value;function(
- 预编译模式下 @sample:value 中 ${item} 不合法! value 里面用 , 分割的每一项必须是 co
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/a55a155a2d7ecc06.
Report an issue: GitHub.