Tencent/APIJSON · error · IllegalArgumentException
预编译模式下 @order:value 中 {item} 不合法! value 里面用 , 分割的每一项必须是 随机函数
Error message
预编译模式下 @order:value 中 {item} 不合法! value 里面用 , 分割的每一项必须是 随机函数 rand() 或 column+ / column- 且其中 column 必须是 1 个单词!并且不要有多余的空格! What it means
Prepared-mode validation of @order:value: after stripping the trailing '+'/'-' sort marker (rand() is handled earlier), the remaining column must be a single word (StringUtil.isName). ORDER BY items cannot be bound parameters, so anything else is rejected to prevent injection.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java:2181
continue;
}
int index = item.endsWith("+") ? item.length() - 1 : -1; //StringUtil.split返回数组中,子项不会有null
String sort;
if (index < 0) {
index = item.endsWith("-") ? item.length() - 1 : -1;
sort = index <= 0 ? "" : " DESC ";
}
else {
sort = " ASC ";
}
String origin = index < 0 ? item : item.substring(0, index);
if (isPrepared()) { //不能通过 ? 来代替,SELECT 'id','name' 返回的就是 id:"id", name:"name",而不是数据库里的值!
//这里既不对origin trim,也不对 ASC/DESC ignoreCase,希望前端严格传没有任何空格的字符串过来,减少传输数据量,节约服务器性能
if (StringUtil.isName(origin) == false) {
throw new IllegalArgumentException("预编译模式下 @order:value 中 " + item + " 不合法! value 里面用 , 分割的"
+ "每一项必须是 随机函数 rand() 或 column+ / column- 且其中 column 必须是 1 个单词!并且不要有多余的空格!");
}
}
keys[i] = gainKey(origin) + sort;
}
return (hasPrefix ? " ORDER BY " : "") + StringUtil.concat(StringUtil.get(keys), joinOrder, ", ");
}
@Override
public Map<String, String> getKeyMap() {
return keyMap;
}
@Override
public AbstractSQLConfig<T, M, L> setKeyMap(Map<String, String> keyMap) {
this.keyMap = keyMap;
return this;View on GitHub (pinned to 5284052872)
Solutions
- Use the marker syntax with bare names: "@order": "date-" for date DESC
- Use "@order": "rand()" for random ordering (special-cased)
- For functional ordering, define it in RAW_MAP and reference via @raw
Example fix
// before
{"@order": "created_at desc"}
// after
{"@order": "created_at-"} Defensive patterns
Strategy: validation
Validate before calling
for (const raw of String(obj['@order'] ?? '').split(',')) {
if (raw === 'rand()') continue;
const col = raw.endsWith('+') || raw.endsWith('-') ? raw.slice(0, -1) : raw;
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(col)) throw new Error(`@order item '${raw}' must be rand() or column+/-`);
} Type guard
const isOrderItemValid = s => s === 'rand()' || /^[A-Za-z_][A-Za-z0-9_]*[+-]?$/.test(s);
Try / catch
try { await api.get(req); } catch (e) { if (e.message.includes('@order')) replaceAscDescWithMarkers(req); else throw e; } Prevention
- Encode direction as +/- suffix, never asc/desc words
- Reject free-text sort fields at the UI layer; use a column dropdown
When it happens
Trigger: "@order": "user id+" (space), "@order": "name asc" , "@order": "LENGTH(name)-" — the origin before the sort suffix fails isName.
Common situations: Writing 'asc'/'desc' (already encoded as +-) or SQL expressions into @order; joining a list with spaces; using function calls for custom ordering.
Related errors
- @group:value 中 value里面用 , 分割的每一项都必须是1个单词!并且不要有空格!
- 字符 {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/1beaf9574ab9a706.
Report an issue: GitHub.