{"record":{"id":"74abaffcd24b28ad","repo":"Tencent/APIJSON","slug":"method-name-key-idkey-idinkey-idke","errorCode":null,"errorMessage":"{method}请求，{name}/{key} 里面 {idKey},{idInKey},{idKey}{}@ 至少传其中一个！","messagePattern":"(.+?)请求，(.+?)/(.+?) 里面 (.+?),(.+?),(.+?)(.+?)@ 至少传其中一个！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java","lineNumber":768,"sourceCode":"\t\t\tthrow new IllegalArgumentException(method + \"请求，\" + name + \"/\" + key\n\t\t\t\t\t+ \" 里面的 \" + idKey + \":value 中value的类型只能是 Long 或 String ！\");\n\t\t}\n\n\n\t\t//批量修改或删除\n\t\tString idInKey = idKey + \"{}\";\n\t\t// id引用, 格式: \"id{}@\": \"sql\"\n\t\tString idRefInKey = getString(robj, idKey + \"{}@\");\n\t\tL idIn = null;\n\t\ttry {\n\t\t\tidIn = get(robj, idInKey); //如果必须传 id{} ，可在Request表中配置NECESSARY\n\t\t} catch (Exception e) {\n\t\t\tthrow new IllegalArgumentException(method + \"请求，\" + name + \"/\" + key\n\t\t\t\t\t+ \" 里面的 \" + idInKey + \":value 中value的类型只能是 [Long] ！\");\n\t\t}\n\t\tif (idIn == null) {\n\t\t\tif (atLeastOne && id == null && idRefInKey == null) {\n\t\t\t\tthrow new IllegalArgumentException(method + \"请求，\" + name + \"/\" + key\n\t\t\t\t\t\t+ \" 里面 \" + idKey + \",\" + idInKey  + \",\" + (idKey + \"{}@\") + \" 至少传其中一个！\");\n\t\t\t}\n\t\t} else {\n\t\t\tif (idIn.size() > maxUpdateCount) { //不允许一次操作 maxUpdateCount 条以上记录\n\t\t\t\tthrow new IllegalArgumentException(method + \"请求，\" + name + \"/\" + key\n\t\t\t\t\t\t+ \" 里面的 \" + idInKey + \":[] 中[]的长度不能超过 \" + maxUpdateCount + \" ！\");\n\t\t\t}\n\t\t\t//解决 id{}: [\"1' OR 1='1'))--\"] 绕过id{}限制\n\t\t\t//new ArrayList<Long>(idIn) 不能检查类型，Java泛型擦除问题，居然能把 [\"a\"] 赋值进去还不报错\n\t\t\tfor (int i = 0; i < idIn.size(); i++) {\n\t\t\t\tObject o = idIn.get(i);\n\t\t\t\tif (o == null) {\n\t\t\t\t\tthrow new IllegalArgumentException(method + \"请求，\" + name + \"/\" + key\n\t\t\t\t\t\t\t+ \" 里面的 \" + idInKey + \":[] 中所有项都不能为 [ null, <= 0 的数字, 空字符串 \\\"\\\" ] 中任何一个 ！\");\n\t\t\t\t}\n\t\t\t\tif (o instanceof Number) {\n\t\t\t\t\t//解决 Windows mysql-5.6.26-winx64 等低于 5.7 的 MySQL 可能 id{}: [0] 生成 id IN(0) 触发 MySQL bug 导致忽略 IN 条件\n\t\t\t\t\t//例如 UPDATE `apijson`.`TestRecord` SET `testAccountId` = -1 WHERE ( (`id` IN (0)) AND (`userId`= 82001) )","sourceCodeStart":750,"sourceCodeEnd":786,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java#L750-L786","documentation":"Thrown by verifyId with atLeastOne=true (batch-write requests) when none of id, id{}, id{}@ is present in the table object. APIJSON refuses UPDATE/DELETE without a row selector because that would update every row.","triggerScenarios":"PUT /put with {\"User\":{\"name\":\"a\"}} — no \"id\", no \"id{}\", no \"id{}@\" key in the User object of a PUT/DELETE request.","commonSituations":"Client builds the update body from a form and forgets to carry the record id; copy-pasting a POST body into a PUT; intending an id reference (id{}@:\"sql\") but mistyping the key.","solutions":["Add the target row id: {\"User\":{\"id\":82001,\"name\":\"a\"}}","For batch, add id{}:[...] or an id reference id{}@:\"...\"","If you genuinely need a WHERE-less operation, reconsider — APIJSON forbids it by design"],"exampleFix":"// before\n{\"User\":{\"name\":\"a\"}}\n// after\n{\"User\":{\"id\":82001,\"name\":\"a\"}}","handlingStrategy":"validation","validationCode":"function hasRowSelector(obj, idKey = 'id') {\n  return obj[idKey] != null || obj[idKey + '{}'] != null || obj[idKey + '{}@'] != null;\n}\n// before PUT/DELETE: if (!hasRowSelector(body[table])) throw new Error('id/id{}/id{}@ required');","typeGuard":null,"tryCatchPattern":"catch (e) { if (/至少传其中一个/.test(e.message)) promptUserToSelectRows(); else throw e; }","preventionTips":["Make the record id a mandatory parameter in your update/delete client functions","Disable the submit button until a target row is selected in edit UIs"],"tags":["apijson","validation","required-field","update-delete"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}