Tencent/APIJSON · error · UnsupportedOperationException
${table}/${k} 不合法!join 关联的 Table 中,join: ?/Table/key 时只能有 1
Error message
${table}/${k} 不合法!join 关联的 Table 中,join: ?/Table/key 时只能有 1 个 key@:value;join: ?/Table 时所有 key@:value 要么是符合 join 格式,要么能直接解析成具体值! What it means
A key@ entry in the joined table object had a path value that the parser could not resolve: getValueByPath(sv) returned null or echoed the input string back, meaning '/Table/key' does not point to an existing value in the current request. Since join: ?/Table/key permits exactly one key@ and join: ?/Table requires every key@ to be resolvable, an UnsupportedOperationException is raised (a TODO marks future JOIN ON support).
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractParser.java:1756
if (StringUtil.isName(k.substring(0, k.length() - 1)) == false) {
throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 中 " + k + " 不合法 !" +
"@ APP JOIN 只允许 key@:/Table/refKey 这种 = 等价连接!");
}
}
refObj.put(k, v);
continue;
}
}
Object rv = getValueByPath(sv);
if (rv != null && rv.equals(sv) == false) {
requestObj.put(k.substring(0, k.length() - 1), rv);
continue;
}
throw new UnsupportedOperationException(table + "/" + k + " 不合法!" + apijson.JSONRequest.KEY_JOIN + " 关联的 Table 中,"
+ "join: ?/Table/key 时只能有 1 个 key@:value;join: ?/Table 时所有 key@:value 要么是符合 join 格式,要么能直接解析成具体值!"); // TODO 支持 join on
}
if (k.startsWith("@")) {
if (JOIN_COPY_KEY_LIST.contains(k)) {
requestObj.put(k, v); // 保留
}
}
else {
if (k.endsWith("@")) {
throw new UnsupportedOperationException(table + "/" + k + " 不合法!" + apijson.JSONRequest.KEY_JOIN + " 关联的 Table 中,"
+ "join: ?/Table/key 时只能有 1 个 key@:value;join: ?/Table 时所有 key@:value 要么是符合 join 格式,要么能直接解析成具体值!"); // TODO 支持 join on
}
if (k.contains("()") == false) { // 不需要远程函数
requestObj.put(k, v); // 保留
}
}View on GitHub (pinned to 5284052872)
Solutions
- Include the referenced table object with the referenced key in the same request: add 'User': { 'id': ... }
- Fix typos in the reference path so '/targetTable/targetKey' matches real keys already present
- Verify the target key exists in the referenced object (it must be literal-valued, not another unresolved reference)
Example fix
// before
{ 'join': '</Moment', 'Moment': { 'userId@': '/User/id' } }
// after
{ 'join': '</Moment', 'Moment': { 'userId@': '/User/id' }, 'User': { 'id': 38710 } } Defensive patterns
Strategy: validation
Validate before calling
function resolveRefPath(req, path) {
if (typeof path !== 'string' || !path.startsWith('/')) return null;
let cur = req;
for (const seg of path.split('/').filter(Boolean)) {
if (cur == null || typeof cur !== 'object' || !(seg in cur)) return null;
cur = cur[seg];
}
return cur;
}
function checkJoinRefs(req) {
for (const [tblKey, tbl] of Object.entries(req)) {
if (tbl && typeof tbl === 'object') {
for (const [k, v] of Object.entries(tbl)) {
if (k.endsWith('@') && typeof v === 'string' && v.startsWith('/') && resolveRefPath(req, v) == null) {
return `${tblKey}/${k}: path ${v} does not resolve in this request`;
}
}
}
}
return null;
} Try / catch
Catch UnsupportedOperationException containing '只能有 1 个 key@:value'; re-check that every /Table/key path exists in the request payload and report the unresolved one.
Prevention
- Every key@ path must point to an existing literal value inside the same request
- Automated test: walk all key@ values and assert they resolve before shipping the request builder
When it happens
Trigger: { 'join': '</Moment', 'Moment': { 'userId@': '/User/id' } } sent without a 'User' object in the same request; or '/User/name' where 'name' is not a key of User; or a path with a typo '/Userr/id'.
Common situations: Forgetting to include the referenced (main) table object in the same request; referencing a key the main table object does not declare; renaming tables after the join request was written.
Related errors
- join:${e.getKey()} 中 ${key} 不合法!必须为 &/Table0,</Table1/key1,@
- join:${e.getKey()}' 对应的 ${tableKey}:{ ${key}: value } 中 valu
- ${e.getKey()}:value 中 value 值 ${targetPath} 不合法!必须为引用赋值的路径 '
- ${e.getKey()}:'/targetTable/targetKey' 中路径对应的 '${targetTable
- ${e.getKey()}:'/targetTable/targetKey' 中路径对应的对象 '${targetTab
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/90fe8e876b5dba55.
Report an issue: GitHub.