Tencent/APIJSON · error · IllegalArgumentException
join:value 中 value 的 alias 值 ${alias} 不合法!必须为 &/Table0,</Tab
Error message
join:value 中 value 的 alias 值 ${alias} 不合法!必须为 &/Table0,</Table1/key1,@/Table1:alias2/key2,... 或 { '&/Table0':{}, '</Table1/key1':{},... } 这种格式!且 Table:alias 的 alias 必须满足英文单词变量名格式! What it means
If a join path carries Table:alias, the alias is validated with StringUtil.isName (non-empty case): it must be a plain identifier word. An alias containing symbols, slashes, brackets, or starting with a digit throws IllegalArgumentException with the grammar reminder.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractParser.java:1646
String arrKey = index2 < 0 ? null : tableKey.substring(0, index2);
if (arrKey != null && isArrayKey(arrKey) == false) {
throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + " 不是合法的数组 key[] !" +
"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中不能有 join: value 键值对!");
}
tableKey = index2 < 0 ? tableKey : tableKey.substring(index2+1);
apijson.orm.Entry<String, String> entry = Pair.parseEntry(tableKey, true);
String table = entry.getKey(); // User
if (StringUtil.isName(table) == false) {
throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":value 中 value 的 Table 值 " + table + " 不合法!"
+ "必须为 &/Table0,</Table1/key1,@/Table1:alias2/key2,... 或 { '&/Table0':{}, '</Table1/key1':{},... } 这种格式!"
+ "且 Table 必须满足大写字母开头的表对象英文单词 key 格式!");
}
String alias = entry.getValue(); // owner
if (StringUtil.isNotEmpty(alias, true) && StringUtil.isName(alias) == false) {
throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":value 中 value 的 alias 值 " + alias + " 不合法!"
+ "必须为 &/Table0,</Table1/key1,@/Table1:alias2/key2,... 或 { '&/Table0':{}, '</Table1/key1':{},... } 这种格式!"
+ "且 Table:alias 的 alias 必须满足英文单词变量名格式!");
}
// 取出Table对应的JSONObject,及内部引用赋值 key:value
M tableObj;
M parentPathObj; // 保留
try {
parentPathObj = arrKey == null ? request : JSON.get(request, arrKey); // 保留
tableObj = parentPathObj == null ? null : JSON.get(parentPathObj, tableKey);
if (tableObj == null) {
throw new NullPointerException("tableObj == null");
}
}
catch (Exception e2) {
throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + tableKey + ":value 中 value 类型不合法!" +
"必须是 {} 这种 Map<String, Object> 格式!" + e2.getMessage());
}View on GitHub (pinned to 5284052872)
Solutions
- Keep the alias a bare identifier: '&/User:owner'
- Use the alias only for disambiguation between multiple joins of the same table
- Put join conditions inside the table object, not in the alias
- Sanitize any dynamic alias to [A-Za-z_][A-Za-z0-9_]* before sending
Example fix
// before
{"@join":"&/User:owner-2/id"}
// after
{"@join":"&/User:owner2/id"} Defensive patterns
Strategy: validation
Validate before calling
if (alias != null && !alias.matches("^[A-Za-z_][A-Za-z0-9_]*$")) throw new IllegalArgumentException("bad join alias: " + alias); Type guard
boolean isValidJoinAlias(String a) { return a == null || a.matches("^[A-Za-z_][A-Za-z0-9_]*$"); } Prevention
- Keep aliases as bare identifiers
- Sanitize dynamic aliases before embedding in join paths
- Remember alias slot is for disambiguation only, not conditions
When it happens
Trigger: "@join":"&/User:owner-2", '@/User:a.b', or '&/User:owner/toId' where the slash makes the alias segment parse into invalid parts. Any non-identifier alias text.
Common situations: Using quoted or spaced aliases; trying to express join ON-conditions in the alias slot; concatenating user input into the alias; thinking alias may include dots for schema qualification.
Related errors
- @join:value 中 value 的 Table 值 {} 不合法!必须为 &/Table0,</Table1/k
- ${e.getKey()}:'/targetTable:targetAlias/targetKey' 中 targetA
- joinType + "/.../" + table + "/" + originKey + " 中字符 " + l.g
- AbstractParser.onJoinParse join 只能是 String 或 Map<String, Ob
- @join:value 中value不合法!必须为 &/Table0/key0,</Table1/key1,... 或
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/c6b078c9502d5ff0.
Report an issue: GitHub.