{"record":{"id":"756b1cdc87a45707","repo":"Tencent/APIJSON","slug":"e-getkey-targettable-targetkey-t","errorCode":null,"errorMessage":"${e.getKey()}:'/targetTable/targetKey' 中路径对应的 '${targetTableKey}':value 中 value 类型不合法！必须是 {} 这种 Map<String, Object> 格式！${e2.getMessage()}","messagePattern":"(.+?):'/targetTable/targetKey' 中路径对应的 '(.+?)':value 中 value 类型不合法！必须是 (.+?) 这种 Map<String, Object> 格式！(.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractParser.java","lineNumber":1849,"sourceCode":"\t\t\t\t}\n\n\t\t\t\tString targetAlias = targetEntry.getValue(); //owner\n\t\t\t\tif (StringUtil.isNotEmpty(targetAlias, true) && StringUtil.isName(targetAlias) == false) {\n\t\t\t\t\tthrow new IllegalArgumentException(e.getKey() + \":'/targetTable:targetAlias/targetKey' 中 targetAlias 值 \" + targetAlias + \" 不合法！必须满足英文单词变量名格式！\");\n\t\t\t\t}\n\n\t\t\t\t//targetTable = targetTableKey;  // 主表允许别名\n\t\t\t\tif (StringUtil.isName(targetTable) == false) {\n\t\t\t\t\tthrow new IllegalArgumentException(e.getKey() + \":'/targetTable/targetKey' 中 targetTable 值 \" + targetTable + \" 不合法！必须满足大写字母开头的表对象英文单词 key 格式！\");\n\t\t\t\t}\n\n\t\t\t\t//对引用的JSONObject添加条件\n\t\t\t\tMap<String, Object> targetObj;\n\t\t\t\ttry {\n\t\t\t\t\ttargetObj = JSON.get(request, targetTableKey);\n\t\t\t\t}\n\t\t\t\tcatch (Exception e2) {\n\t\t\t\t\tthrow new IllegalArgumentException(e.getKey() + \":'/targetTable/targetKey' 中路径对应的 '\" + targetTableKey + \"':value 中 value 类型不合法！必须是 {} 这种 Map<String, Object> 格式！\" + e2.getMessage());\n\t\t\t\t}\n\n\t\t\t\tif (targetObj == null) {\n\t\t\t\t\tthrow new IllegalArgumentException(e.getKey() + \":'/targetTable/targetKey' 中路径对应的对象 '\" + targetTableKey + \"':{} 不存在或值为 null ！必须是 {} 这种 Map<String, Object> 格式！\");\n\t\t\t\t}\n\n\t\t\t\tJoin.On on = new Join.On();\n\t\t\t\ton.setKeyAndType(j.getJoinType(), j.getTable(), originKey);\n\t\t\t\tif (StringUtil.isName(on.getKey()) == false) {\n\t\t\t\t\tthrow new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + \":value 中 value 的 key@ 中 key 值 \" + on.getKey() + \" 不合法！必须满足英文单词变量名格式！\");\n\t\t\t\t}\n\n\t\t\t\ton.setOriginKey(originKey);\n\t\t\t\ton.setOriginValue((String) refEntry.getValue());\n\t\t\t\ton.setTargetTableKey(targetTableKey);\n\t\t\t\ton.setTargetTable(targetTable);\n\t\t\t\ton.setTargetAlias(targetAlias);\n\t\t\t\ton.setTargetKey(targetKey);","sourceCodeStart":1831,"sourceCodeEnd":1867,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java#L1831-L1867","documentation":"The parser resolves the target table object of an ON reference via JSON.get(request, targetTableKey). If that lookup throws (path navigation through a non-object, e.g. an array or a String mid-path), the exception is wrapped in this IllegalArgumentException telling you the target ':value' is not a Map<String, Object>.","triggerScenarios":"'userId@': '/User[]/User/id' where 'User[]' is a List (cannot be navigated as object); '/User:name/id' where 'name' is a plain String; paths whose intermediate segments hit non-object values.","commonSituations":"Referencing a table inside an array by its wrapper key; deep paths copied from response JSON rather than request structure; intermediate segment collides with a plain column name.","solutions":["Reference the table object directly at the level where it is a Map: '/User/id', not '/User[]/User/id'","Make sure every intermediate segment in the path is an object key, ending at the target table object"],"exampleFix":"// before\n{ 'join': '</Comment', 'Comment': { 'userId@': '/User[]/User/id' } }\n// after\n{ 'join': '</Comment', 'Comment': { 'userId@': '/User/id' }, 'User': { 'id': 38710 } }","handlingStrategy":"type-guard","validationCode":"function resolveTable(req, tableKey) {\n  let cur = req;\n  for (const seg of tableKey.split('/').filter(Boolean)) {\n    if (cur == null || typeof cur !== 'object' || Array.isArray(cur)) return null;\n    cur = cur[seg];\n  }\n  return cur && typeof cur === 'object' && !Array.isArray(cur) ? cur : null;\n}\nfunction checkRefTablesAreObjects(req) {\n  for (const tbl of Object.values(req)) {\n    if (tbl && typeof tbl === 'object') {\n      for (const [k, v] of Object.entries(tbl)) {\n        if (!k.endsWith('@') || typeof v !== 'string' || !v.startsWith('/')) continue;\n        if (resolveTable(req, v.split('/').slice(1, -1).join('/')) == null) {\n          return `${k}: '${v}' does not lead to an object`;\n        }\n      }\n    }\n  }\n  return null;\n}","typeGuard":"const isPlainObject = (v) => v != null && typeof v === 'object' && !Array.isArray(v);","tryCatchPattern":"Catch IllegalArgumentException with '必须是 {} 这种 Map<String, Object> 格式'; rewrite the path to address the table object directly.","preventionTips":["Reference paths must traverse only objects — never arrays or scalar keys","Model request paths from the request structure, not from response JSON"],"tags":["apijson","join","type-error","path-resolution"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}