{"record":{"id":"0cdfedbf9046466d","repo":"Tencent/APIJSON","slug":"request-allow-partial-update-fail-value-k-0cdfed","errorCode":null,"errorMessage":"后端 Request 表中 ALLOW_PARTIAL_UPDATE_FAIL:value 中 {key} 不合法！[] 前必须有名字！","messagePattern":"后端 Request 表中 ALLOW_PARTIAL_UPDATE_FAIL:value 中 (.+?) 不合法！\\[\\] 前必须有名字！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java","lineNumber":1243,"sourceCode":"\t\t// 校验并配置允许批量增删改部分失败<<<<<<<<<<<<<<<<<<<\n\t\tString allowPartialUpdateFail = StringUtil.get(getString(target, ALLOW_PARTIAL_UPDATE_FAIL.name()));\n\t\tString[] partialFails = StringUtil.split(allowPartialUpdateFail);\n\t\tif (partialFails != null && partialFails.length > 0) {\n\t\t\tfor (String key : partialFails) {\n                if (isArrayKey(key) == false) {\n                    throw new IllegalArgumentException(\"后端 Request 表中 \" + ALLOW_PARTIAL_UPDATE_FAIL.name()\n                            + \":value 中 \" + key + \" 不合法！必须以 [] 结尾！\");\n                }\n                if (target.get(key) instanceof Collection == false) {\n                    throw new IllegalArgumentException(\"后端 Request 表中 \" + ALLOW_PARTIAL_UPDATE_FAIL.name()\n                            + \":value 中 \" + key + \" 对应的 \" + key + \":[] 不存在！\");\n                }\n\n                // 可能 Table[] 和 Table:alias[] 冲突  int index = key.indexOf(\":\");\n                // String k = index < 0 ? key.substring(0, key.length() - 2) : key.substring(0, index);\n                String k = key.substring(0, key.length() - 2);\n                if (k.isEmpty()) {\n                    throw new IllegalArgumentException(\"后端 Request 表中 \" + ALLOW_PARTIAL_UPDATE_FAIL.name()\n                            + \":value 中 \" + key + \" 不合法！[] 前必须有名字！\");\n                }\n\n\t\t\t\tAbstractSQLConfig.ALLOW_PARTIAL_UPDATE_FAIL_TABLE_MAP.putIfAbsent(k, \"\");\n\t\t\t}\n\t\t}\n\t\t// 校验并配置允许部分批量增删改失败>>>>>>>>>>>>>>>>>>>\n\n\n\t\tString[] nks = ifObj == null ? null : StringUtil.split(getString(real, KEY_NULL));\n\t\tCollection<?> nkl = nks == null || nks.length <= 0 ? new HashSet<>() : Arrays.asList(nks);\n\n\t\tSet<Map.Entry<String, Object>> ifSet = ifObj == null ? null : ifObj.entrySet();\n\t\tif (ifIsStr || (ifSet != null && ifSet.isEmpty() == false)) {\n\t\t\t// 没必要限制，都是后端配置的，安全可控，而且可能确实有特殊需求，需要 id, @column 等\n//\t\t\tList<String> condKeys = new ArrayList<>(Arrays.asList(apijson.JSONMap.KEY_ID, apijson.JSONMap.KEY_ID_IN\n//\t\t\t\t\t, apijson.JSONMap.KEY_USER_ID, apijson.JSONMap.KEY_USER_ID_IN));\n//\t\t\tcondKeys.addAll(apijson.JSONMap.TABLE_KEY_LIST);","sourceCodeStart":1225,"sourceCodeEnd":1261,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java#L1225-L1261","documentation":"After stripping the trailing '[]' from an ALLOW_PARTIAL_UPDATE_FAIL token, the remaining name must be non-empty ('String k = key.substring(0, key.length()-2); if (k.isEmpty()) throw'). A token that is exactly '[]' (no table name before the brackets) is meaningless and rejected. This guards against malformed values like a stray '[]' entry produced by string-splitting or bad config edits.","triggerScenarios":"ALLOW_PARTIAL_UPDATE_FAIL is set to \"[]\" or contains '[]' among its space/comma-separated tokens (e.g. \"User[],[]\"). The check runs before the token is put into AbstractSQLConfig.ALLOW_PARTIAL_UPDATE_FAIL_TABLE_MAP, so the request fails during verification.","commonSituations":"Config generated programmatically where the table-name variable was empty/null and concatenated as \"\"+\"[]\"; manual JSON editing that leaves an empty key; copy-paste of a placeholder from docs without replacing <Table>[].","solutions":["Remove the bare '[]' token so every entry has a table name, e.g. \"User[]\".","If generating ALLOW_PARTIAL_UPDATE_FAIL in code, skip empty table names before joining tokens: tokens.stream().filter(t -> !t.isEmpty()).map(t -> t + \"[]\")...","Validate the config once after editing: every token must match ^[A-Za-z0-9_]+\\[\\]$."],"exampleFix":"// before\n{\"ALLOW_PARTIAL_UPDATE_FAIL\":\"[]\"}\n// after\n{\"ALLOW_PARTIAL_UPDATE_FAIL\":\"User[]\",\"User[]\":[]}","handlingStrategy":"validation","validationCode":"String buildPartialFail(List<String> tables) {\n  List<String> t = tables == null ? List.of() : tables.stream()\n      .filter(x -> x != null && !x.isEmpty().trim()).map(x -> x + \"[]\").collect(Collectors.toList());\n  return t.isEmpty() ? null : String.join(\",\", t);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never build ALLOW_PARTIAL_UPDATE_FAIL by naive concatenation of a possibly-empty variable with \"[]\".","Add unit test asserting no generated token equals \"[]\"."],"tags":["apijson","server-config","request-table","input-validation"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}