{"record":{"id":"1e6ba177eaf9a858","repo":"Tencent/APIJSON","slug":"method-name-key-tabl","errorCode":null,"errorMessage":"{method}请求，请在 {name} 内传 {key}:[{ ... }] ，批量新增 Table[]:value 中 value 必须是包含表对象的非空数组！其中每个子项 { ... } 都是 tag:{tag} 对应单个新增的 structure ！","messagePattern":"(.+?)请求，请在 (.+?) 内传 (.+?):\\[(.+?)\\] ，批量新增 Table\\[\\]:value 中 value 必须是包含表对象的非空数组！其中每个子项 (.+?) 都是 tag:(.+?) 对应单个新增的 structure ！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java","lineNumber":721,"sourceCode":"\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 {\n\t\t\t\tif ((method == POST || method == PUT) && isArrayKey(key)) {\n\t\t\t\t\tif (rarray == null || rarray.isEmpty()) {\n\t\t\t\t\t\tthrow new IllegalArgumentException(method + \"请求，请在 \" + name + \" 内传 \" + key + \":[{ ... }] \"\n\t\t\t\t\t\t\t\t+ \"，批量新增 Table[]:value 中 value 必须是包含表对象的非空数组！其中每个子项 { ... } 都是\"\n\t\t\t\t\t\t\t\t+ \" tag:\" + key.substring(0, key.length() - 2) + \" 对应单个新增的 structure ！\");\n\t\t\t\t\t}\n\t\t\t\t\tif (rarray.size() > maxUpdateCount) {\n\t\t\t\t\t\tthrow new IllegalArgumentException(method + \"请求，\" + name + \"/\" + key\n\t\t\t\t\t\t\t\t+ \" 里面的 \" + key + \":[{ ... }] 中 [] 的长度不能超过 \" + maxUpdateCount + \" ！\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn super.onParseJSONArray(key, tarray, rarray);\n\t\t\t}\n\t\t});\n\n\t}\n\n\t/**\n\t * @param method\n\t * @param name\n\t * @param key","sourceCodeStart":703,"sourceCodeEnd":739,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java#L703-L739","documentation":"In onParseJSONArray during structure validation: for POST or PUT on a batch array key (ending in '[]', e.g. \"Comment[]\"), the request array must be non-null and non-empty, and each element an object representing one row. A null/empty array throws IllegalArgumentException explaining that Table[]:value must be a non-empty array of table objects tagged by the base key.","triggerScenarios":"A POST/PUT sends {\"Comment[]\": []} or omits the array while the structure/request uses the batch form; isArrayKey(key) is true for the method and rarray == null || rarray.isEmpty() triggers the throw.","commonSituations":"UI 'add all' flow with an empty selection serializing as []; client omits the key when the list is empty but the tag still targets the batch key; refactoring from single-object to batch form leaving [] placeholders.","solutions":["Populate the array with at least one table object: {\"Comment[]\": [{\"content\":\"a\"}, {\"content\":\"b\"}]}.","Skip the request entirely client-side when there is nothing to insert — do not send an empty batch.","For PUT-style partial updates, ensure each element still contains the id condition needed by verifyId."],"exampleFix":"// before\nPOST { \"Comment[]\": [], \"tag\": \"Comment[]\" }\n\n// after\nPOST { \"Comment[]\": [ { \"momentId\": 1, \"content\": \"hi\" } ], \"tag\": \"Comment[]\" }","handlingStrategy":"validation","validationCode":"if ((method == POST || method == PUT) && key.endsWith(\"[]\")\n        && (arr == null || arr.isEmpty())) {\n    clientError(\"batch key \" + key + \" requires a non-empty array of objects\");\n}","typeGuard":"boolean isNonEmptyBatchArray(String key, List<Object> arr, RequestMethod m) { return !(m == RequestMethod.POST || m == RequestMethod.PUT) || !key.endsWith(\"[]\") || (arr != null && !arr.isEmpty()); }","tryCatchPattern":"catch (IllegalArgumentException e) when message contains \"批量新增\" -> 400; skip the call when the selection is empty rather than sending [].","preventionTips":["Suppress the batch request when the client list is empty — never serialize empty arrays.","Validate every element is an object before sending batch requests."],"tags":["apijson","validation","batch-operation","post"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}