Tencent/APIJSON · error · IllegalArgumentException
join:${e.getKey()} 中 ${key} 不合法!必须为 &/Table0,</Table1/key1,@
Error message
join:${e.getKey()} 中 ${key} 不合法!必须为 &/Table0,</Table1/key1,@/Table1:alias2/key2,... 或 { '&/Table0':{}, '</Table1/key1':{},... } 这种格式!且 Table:alias 的 alias 必须满足英文单词变量名格式! What it means
When a join path specifies an explicit ON key (the segment after the last '/', e.g. '@/Comment/toId@'), that key must be a reference-assignment key ending with '@'. This IllegalArgumentException fires when the trailing segment does not end with '@' (indexOf('@') != length-1), i.e. it is not a reference-assignment key at all.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractParser.java:1686
throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ join: value } 中 value 不合法!" +
"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中不能有 join: value 键值对!");
}
Integer subPage = getInteger(parentPathObj, apijson.JSONRequest.KEY_PAGE);
if (subPage != null && subPage != 0) {
throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ page: value } 中 value 不合法!" +
"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中 page 值只能为 null 或 0 !");
}
}
boolean isAppJoin = "@".equals(joinType);
M refObj = JSON.createJSONObject();
String key = index < 0 ? null : path.substring(index + 1); // id@
if (key != null) { // 指定某个 key 为 JOIN ON 条件
if (key.indexOf("@") != key.length() - 1) {
throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":" + e.getKey() + " 中 " + key + " 不合法!"
+ "必须为 &/Table0,</Table1/key1,@/Table1:alias2/key2,... 或 { '&/Table0':{}, '</Table1/key1':{},... } 这种格式!"
+ "且 Table:alias 的 alias 必须满足英文单词变量名格式!");
}
if (tableObj.get(key) instanceof String == false) {
throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":" + e.getKey() + "' 对应的 "
+ tableKey + ":{ " + key + ": value } 中 value 类型不合法!必须为同层级引用赋值路径 String!");
}
if (isAppJoin && StringUtil.isName(key.substring(0, key.length() - 1)) == false) {
throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 中 " + key + " 不合法 !" +
"@ APP JOIN 只允许 key@:/Table/refKey 这种 = 等价连接!");
}
refObj.put(key, getString(tableObj, key));
}
View on GitHub (pinned to 5284052872)
Solutions
- Append '@' to the last path segment: '@/Comment/toId' -> '@/Comment/toId@'
- Ensure the referenced key exists inside the joined table object as a String whose value is the reference path (e.g. Comment: { 'toId@': '/User/id' })
Example fix
// before
{ 'join': '@/Comment/toId', 'Comment': { 'toId@': '/User/id' } }
// after
{ 'join': '@/Comment/toId@', 'Comment': { 'toId@': '/User/id' } } Defensive patterns
Strategy: validation
Validate before calling
function checkJoinPaths(joinValue) {
const paths = typeof joinValue === 'string' ? [joinValue] : Object.keys(joinValue);
const bad = paths.filter(p => {
const rest = p.substring(p.indexOf('/') + 1);
const seg = rest.substring(rest.lastIndexOf('/') + 1);
return seg.length > 0 && !seg.endsWith('@');
});
return bad.length ? `join ON key must end with '@': ${bad.join(', ')}` : null;
} Type guard
const isJoinOnKey = (seg) => /^[A-Za-z_][A-Za-z0-9_]*@$/.test(seg);
Try / catch
catch IllegalArgumentException containing '必须为 &/Table0' when the message names your join key -> append '@' to the last path segment and retry once.
Prevention
- Always name join ON keys with the trailing '@' ('toId@', never 'toId')
- Centralize join-path building in one helper that enforces the ?/Table/key@ shape
When it happens
Trigger: join values like '@/Comment/toId', '</Moment/id', or '&/User:owner/userId@:' where the final path segment lacks the trailing '@'. The parser takes path.substring(index+1) as the ON key and requires it to look like 'key@'.
Common situations: Writing the join ON column name in SQL style ('toId') instead of APIJSON reference style ('toId@'); renaming keys during a refactor and dropping the '@' suffix; copying examples from docs that show the plain column name.
Related errors
- join:'${e.getKey()}' 对应的 ${arrKey}:{ page: value } 中 value 不
- join:${e.getKey()}' 对应的 ${tableKey}:{ ${key}: value } 中 valu
- join:'${e.getKey()}' 中 ${key} 不合法 !@ APP JOIN 只允许 key@:/Tabl
- join:${e.getKey()} 中 ${k} 不合法!@ APP JOIN 必须有且只有一个引用赋值键值对!
- join:'${e.getKey()}' 中 ${k} 不合法 !@ APP JOIN 只允许 key@:/Table/
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/d7193af0b31288aa.
Report an issue: GitHub.