{"record":{"id":"324e2c62a9af1b6a","repo":"Tencent/APIJSON","slug":"key-value-value-object","errorCode":null,"errorMessage":"{key}:value 的 value 不合法！类型必须是 OBJECT ，结构为 {} !","messagePattern":"(.+?):value 的 value 不合法！类型必须是 OBJECT ，结构为 (.+?) !","errorType":"validation","errorClass":"UnsupportedDataTypeException","httpStatus":400,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java","lineNumber":1017,"sourceCode":"\t\t\t\tif (key == null || OPERATION_KEY_LIST.contains(key)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n                Object tvalue = entry.getValue();\n                Object rvalue = real.get(key);\n\t\t\t\tif (rvalue != null && stringKeyList != null && stringKeyList.contains(key)) {\n\t\t\t\t\trvalue = toJSONString(rvalue);\n\t\t\t\t}\n\t\t\t\tif (rvalue != null && trimKeyList != null && trimKeyList.contains(key)) {\n\t\t\t\t\trvalue = StringUtil.trim(rvalue);\n\t\t\t\t}\n\n\t\t\t\tif (callback.onParse(key, tvalue, rvalue) == false) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (tvalue instanceof Map<?, ?>) { // JSONRequest，往下一级提取\n\t\t\t\t\tif (rvalue != null && rvalue instanceof Map<?, ?> == false) {\n\t\t\t\t\t\tthrow new UnsupportedDataTypeException(key + \":value 的 value 不合法！类型必须是 OBJECT ，结构为 {} !\");\n\t\t\t\t\t}\n\t\t\t\t\ttvalue = callback.onParseJSONObject(key, (M) tvalue, (M) rvalue);\n\n\t\t\t\t\tobjKeySet.add(key);\n\t\t\t\t} else if (tvalue instanceof List<?>) { // L\n\t\t\t\t\tif (rvalue != null && rvalue instanceof List<?> == false) {\n\t\t\t\t\t\tthrow new UnsupportedDataTypeException(key + \":value 的 value 不合法！类型必须是 ARRAY ，结构为 [] !\");\n\t\t\t\t\t}\n\t\t\t\t\ttvalue = callback.onParseJSONArray(key, (L) tvalue, (L) rvalue);\n\n\t\t\t\t\tif ((method == POST || method == PUT) && isArrayKey(key)) {\n\t\t\t\t\t\tobjKeySet.add(key);\n\t\t\t\t\t}\n\t\t\t\t} else { // 其它Object\n\t\t\t\t\ttvalue = callback.onParseObject(key, tvalue, rvalue);\n\t\t\t\t}\n\n\t\t\t\tif (tvalue != null) { // 可以在target中加上一些不需要客户端传的键值对","sourceCodeStart":999,"sourceCodeEnd":1035,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java#L999-L1035","documentation":"Thrown during template-value merge in verify: the target (Request-table template) declares a key whose value is an OBJECT ({}), but the client sent a non-object (scalar or array) for the same key. The request structure must mirror the template structure.","triggerScenarios":"Template has \"User\":{\"address\":{}} but the client sends {\"User\":{\"address\":\"Beijing\"}} — rvalue is not a Map while tvalue is.","commonSituations":"API evolution: a field was promoted from scalar to nested object in the template while old clients still send the scalar; client built from outdated docs; template authored with {} as a placeholder meaning 'any object'.","solutions":["Send the value as an object matching the template: {\"address\":{\"city\":\"Beijing\"}}","If the scalar form is intended, change the Request-table template value to a scalar","Version the endpoint and keep the old template for legacy clients"],"exampleFix":"// before\n{\"User\":{\"address\":\"Beijing\"}}\n// after\n{\"User\":{\"address\":{\"city\":\"Beijing\"}}}","handlingStrategy":"type-guard","validationCode":"// template: {address: {}} -> require object\nfunction assertShape(value, template) {\n  for (const k of Object.keys(template)) {\n    const t = template[k], v = value[k];\n    if (v != null && t != null && typeof t === 'object' && !Array.isArray(t) && typeof v !== 'object') {\n      throw new TypeError(`${k} must be an object per template`);\n    }\n  }\n}","typeGuard":"const matchesTemplateShape = (v, t) => t instanceof Object && !(t instanceof Array) ? (v == null || v instanceof Object && !(v instanceof Array)) : true;","tryCatchPattern":null,"preventionTips":["Generate client types from the Request-table template so shapes cannot drift","Treat template {} and [] as literal shape requirements, not placeholders"],"tags":["apijson","type-mismatch","structure","request-table"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}