{"record":{"id":"0981fd8579cca6db","repo":"Tencent/APIJSON","slug":"method-name-key","errorCode":null,"errorMessage":"{method}请求，请在 {name} 内传 {key}:{} ！","messagePattern":"(.+?)请求，请在 (.+?) 内传 (.+?):(.+?) ！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java","lineNumber":671,"sourceCode":"\t\t}\n\n\t\t//已在 Verifier 中处理\n\t\t//\t\tif (get(getString(request, apijson.JSONMap.KEY_ROLE)) == ADMIN) {\n\t\t//\t\t\tthrow new IllegalArgumentException(\"角色设置错误！不允许在写操作Request中传 \" + name +\n\t\t//\t\t\t\t\t\":{ \" + apijson.JSONMap.KEY_ROLE + \":admin } ！\");\n\t\t//\t\t}\n\n\n\t\t//解析\n\t\treturn parse(method, name, target, request, database, datasource, namespace, catalog, schema, idCallback, parser, new OnParseCallback<T, M, L>() {\n\n\t\t\t@Override\n\t\t\tpublic M onParseJSONObject(String key, M tobj, M robj) throws Exception {\n\t\t\t\t//\t\t\t\tLog.i(TAG, \"verifyRequest.parse.onParseJSONObject  key = \" + key + \"; robj = \" + robj);\n\n\t\t\t\tif (robj == null) {\n\t\t\t\t\tif (tobj != null) {//不允许不传Target中指定的Table\n\t\t\t\t\t\tthrow new IllegalArgumentException(method + \"请求，请在 \" + name + \" 内传 \" + key + \":{} ！\");\n\t\t\t\t\t}\n\t\t\t\t} else if (isTableKey(key)) {\n\t\t\t\t\tString db = getString(request, KEY_DATABASE);\n\t\t\t\t\tString ds = getString(request, KEY_DATASOURCE);\n\t\t\t\t\tString ns = getString(request, KEY_NAMESPACE);\n\t\t\t\t\tString cl = getString(request, KEY_CATALOG);\n\t\t\t\t\tString sh = getString(request, KEY_SCHEMA);\n\t\t\t\t\tif (StringUtil.isEmpty(db, false)) {\n\t\t\t\t\t\tdb = database;\n\t\t\t\t\t}\n\t\t\t\t\tif (StringUtil.isEmpty(ds, false)) {\n\t\t\t\t\t\tds = datasource;\n\t\t\t\t\t}\n\t\t\t\t\tif (StringUtil.isEmpty(ns, false)) {\n\t\t\t\t\t\tns = namespace;\n\t\t\t\t\t}\n\t\t\t\t\tif (StringUtil.isEmpty(cl, false)) {\n\t\t\t\t\t\tcl = catalog;","sourceCodeStart":653,"sourceCodeEnd":689,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java#L653-L689","documentation":"During structure validation in verifyRequest's parse callback onParseJSONObject: if the request object for a key is null but the target (structure) defines an object for that key, IllegalArgumentException demands the key be passed as {key}:{}. Structures mark required table objects; omitting a table the structure says must be present is a contract violation.","triggerScenarios":"A POST/PUT with a structure (Request table row) that specifies table object \"User\" in its target, while the client's request JSON omits \"User\" entirely; robj == null with tobj != null triggers the throw.","commonSituations":"Client version drift — newer optional-field handling drops a table the structure still requires; hand-written requests missing a mandatory sub-table; structure row edited to require a table that the front-end flow never sends; nested batch structures where an inner table is skipped.","solutions":["Add the missing table object to the request: {\"<key>\": { ... }} as required by the structure.","If the table should genuinely be optional, update the structure/Request table row (target JSON) so it does not force the key.","Keep structure definitions and the front-end request builder in sync via a shared schema or generated types."],"exampleFix":"// before\n// structure requires: { \"User\": { \"MUST\": \"id\" } }\n{ \"tag\": \"User\", \"params\": { } }\n\n// after\n{ \"tag\": \"User\", \"params\": { \"User\": { \"id\": 1 } } }","handlingStrategy":"validation","validationCode":"// client: before send, ensure every table key required by the structure's target is present\nfor (String k : structureTargetKeys) {\n    if (isTableKey(k) && !request.containsKey(k)) clientError(\"missing required table object \" + k);\n}","typeGuard":"boolean satisfiesRequiredTables(Set<String> required, Map<String,Object> req) { return required.stream().filter(this::isTableKey).allMatch(req::containsKey); }","tryCatchPattern":"catch (IllegalArgumentException e) when message contains \"内传\" -> 400 with the missing key name; client re-renders the form section.","preventionTips":["Generate request DTOs from the structure (Request table) so required tables are compile-time visible.","Version structures with the client release; reject mismatched structure/client pairs at the edge."],"tags":["apijson","validation","structure","request-contract"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}