{"record":{"id":"6fa796d93cc68d76","repo":"Tencent/APIJSON","slug":"key-value-value-string-map-string","errorCode":null,"errorMessage":"${key}: value 中 value 类型错误，只能是 String 或 Map<String, Object> {} ！","messagePattern":"(.+?): value 中 value 类型错误，只能是 String 或 Map<String, Object> (.+?) ！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractParser.java","lineNumber":2326,"sourceCode":"\t\tObject val = request.get(key);\n\t\tMap<String, Object> obj = val instanceof Map<?, ?> ? JSON.get(request, key) : null;\n\t\tif (obj == null) {\n\t\t\tif (val instanceof String) {\n\t\t\t\tString[] tbls = StringUtil.split((String) val);\n\t\t\t\tif (tbls != null && tbls.length > 0) {\n\t\t\t\t\tobj = new LinkedHashMap<String, Object>();\n\t\t\t\t\tfor (String tbl : tbls) {\n\t\t\t\t\t\tif (obj.containsKey(tbl)) {\n\t\t\t\t\t\t\tthrow new ConflictException(key + \": value 中 \" + tbl + \" 已经存在，不能重复！\");\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tobj.put(tbl, isPost && isTableArray(tbl)\n\t\t\t\t\t\t\t\t? tbl.substring(0, tbl.length() - 2) + \":[]\" : \"\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new IllegalArgumentException(key + \": value 中 value 类型错误，只能是 String 或 Map<String, Object> {} ！\");\n\t\t\t}\n\t\t}\n\n\t\tSet<Entry<String, Object>> set = obj == null ? new HashSet<>() : obj.entrySet();\n\t\tfor (Entry<String, Object> objEntry : set) {\n\t\t\tString objKey = objEntry == null ? null : objEntry.getKey();\n\t\t\tif (objKey == null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tMap<String, Object> objAttrMap = new HashMap<>();\n\t\t\tobjAttrMap.put(KEY_METHOD, keyMethod);\n\t\t\tkeyObjectAttributesMap.put(objKey, objAttrMap);\n\n\t\t\tObject objVal = objEntry.getValue();\n\t\t\tMap<String, Object> objAttrJson = objVal instanceof Map<?, ?> ? JSON.getMap(obj, objKey) : null;\n\t\t\tif (objAttrJson == null) {\n\t\t\t\tif (objVal instanceof String) {","sourceCodeStart":2308,"sourceCodeEnd":2344,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractParser.java#L2308-L2344","documentation":"Thrown by AbstractParser when parsing a method directive key (@post, @put, @delete, ...) whose top-level value is neither a String nor a Map<String,Object>. The directive value is either a tag string (e.g. \"User\") or a map of table names to per-table tags/attribute objects; any other JSON type is rejected with IllegalArgumentException.","triggerScenarios":"A batch/CRUD request body containing e.g. \"@post\": 123, \"@post\": true, or \"@post\": [\"User\"] — the value under the method directive key is a number, boolean, or array instead of \"tag\" or {\"User\": \"tag\"}.","commonSituations":"Frontend builds the directive value dynamically and accidentally serializes a number or array; copy-paste from docs examples that omit quotes around the tag; JSON produced by a template engine inserting a non-string variable.","solutions":["Change the directive value to a plain tag string: \"@post\": \"User\"","Or use the map form with String/Map values per table: \"@post\": {\"User\": {\"tag\": \"User\"}}","If the value comes from client code, log its runtime type before sending and coerce it to a string"],"exampleFix":"// before\n{\"@post\": 123, \"User\": {\"name\": \"a\"}}\n// after\n{\"@post\": \"User\", \"User\": {\"name\": \"a\"}}","handlingStrategy":"validation","validationCode":"// before sending\nconst v = req['@post'] ?? req['@put'] ?? req['@delete'];\nif (v != null && !(typeof v === 'string' || (typeof v === 'object' && !Array.isArray(v)))) {\n  throw new Error('method directive value must be a tag string or an object');\n}","typeGuard":"const isDirectiveValue = v => typeof v === 'string' || (v !== null && typeof v === 'object' && !Array.isArray(v));","tryCatchPattern":"try { await client.crud(req); } catch (e) { if (/类型错误，只能是 String 或 Map/.test(e.message)) fixDirectiveType(req); else throw e; }","preventionTips":["Build method directives from a typed helper, never inline JSON.parse of user input","Add a JSON-schema check for @post/@put/@delete values"],"tags":["apijson","request-validation","batch-request"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}