{"record":{"id":"d6c9221ee9e8c046","repo":"Tencent/APIJSON","slug":"method-name-key-idkey","errorCode":null,"errorMessage":"{method}请求，{name}/{key} 不能传 {idKey} ！","messagePattern":"(.+?)请求，(.+?)/(.+?) 不能传 (.+?) ！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java","lineNumber":700,"sourceCode":"\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;\n\t\t\t\t\t}\n\t\t\t\t\tif (StringUtil.isEmpty(sh, false)) {\n\t\t\t\t\t\tsh = schema;\n\t\t\t\t\t}\n\n\t\t\t\t\tString idKey = idCallback == null ? null : idCallback.getIdKey(db, ds, ns, cl, sh, key);\n\t\t\t\t\tString finalIdKey = StringUtil.isEmpty(idKey, false) ? KEY_ID : idKey;\n\n\t\t\t\t\tif (method == POST) {\n\t\t\t\t\t\tif (robj.containsKey(finalIdKey)) {\n\t\t\t\t\t\t\tthrow new IllegalArgumentException(method + \"请求，\" + name + \"/\" + key + \" 不能传 \" + finalIdKey + \" ！\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tBoolean atLeastOne = tobj == null ? null : getBoolean(tobj, Operation.IS_ID_CONDITION_MUST.name());\n\t\t\t\t\t\tif (Boolean.TRUE.equals(atLeastOne) || RequestMethod.isUpdateMethod(method)) {\n\t\t\t\t\t\t\tverifyId(method.name(), name, key, robj, finalIdKey, maxUpdateCount, atLeastOne != null ? atLeastOne : IS_UPDATE_MUST_HAVE_ID_CONDITION);\n\n\t\t\t\t\t\t\tString userIdKey = idCallback == null ? null : idCallback.getUserIdKey(db, ds, ns, cl, sh, key);\n\t\t\t\t\t\t\tString finalUserIdKey = StringUtil.isEmpty(userIdKey, false) ? KEY_USER_ID : userIdKey;\n\t\t\t\t\t\t\tverifyId(method.name(), name, key, robj, finalUserIdKey, maxUpdateCount, false);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn verifyRequest(method, key, tobj, robj, maxUpdateCount, database, datasource, namespace, catalog, schema, idCallback, parser);\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tprotected L onParseJSONArray(String key, L tarray, L rarray) throws Exception {","sourceCodeStart":682,"sourceCodeEnd":718,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java#L682-L718","documentation":"In verifyRequest's table-object branch: for POST requests the client must not supply the primary id key (resolved via IdCallback.getIdKey, default 'id') because ids are generated server-side. If robj.containsKey(finalIdKey) is true, IllegalArgumentException rejects the request with '{method}请求，{name}/{key} 不能传 {idKey}！'.","triggerScenarios":"A POST body includes \"id\" (or the configured id key) inside a table object, e.g. {\"User\": {\"id\": 5, \"name\":\"x\"}}; the POST branch detects the key and throws before the insert is built.","commonSituations":"Client reuses an update-form/model that carries id for create; ORM-style DTO serialized wholesale; front-end generates ids offline (uuid-thinking) while the server uses IdCallback; changing IdCallback id key but old clients still send the previous key.","solutions":["Remove the id field from POST bodies — let IdCallback assign ids on insert.","If the client truly supplies ids (e.g. UUID strings), configure a custom IdCallback and keep clients consistent with it; do not mix server-generated and client-sent ids for the same table.","Strip id in the client serializer for create operations (e.g. lodash omit / DTO projection)."],"exampleFix":"// before\nPOST { \"User\": { \"id\": 5, \"name\": \"x\" } }\n\n// after\nPOST { \"User\": { \"name\": \"x\" } }","handlingStrategy":"validation","validationCode":"if (method == RequestMethod.POST && tableObj.containsKey(idKey)) {\n    clientError(\"POST must not carry \" + idKey + \"; ids are generated server-side\");\n}","typeGuard":"boolean isIdFreePost(Map<String,Object> tableObj, String idKey) { return !tableObj.containsKey(idKey); }","tryCatchPattern":"catch (IllegalArgumentException e) when message contains \"不能传\" -> 400; strip the id key client-side and resubmit once.","preventionTips":["In create serializers, omit id (and createdAt-style server fields) explicitly.","Keep create and update DTOs separate so id never leaks into create payloads."],"tags":["apijson","validation","post","id-generation"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}