{"record":{"id":"0f10a16dbfff4dac","repo":"Tencent/APIJSON","slug":"method-rk-key-value","errorCode":null,"errorMessage":"{method} 请求，{rk} 不合法！非开放请求不允许传 @key:value ！","messagePattern":"(.+?) 请求，(.+?) 不合法！非开放请求不允许传 @key:value ！","errorType":"validation","errorClass":"UnsupportedOperationException","httpStatus":400,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java","lineNumber":1126,"sourceCode":"\n\t\t// 判断不允许传的key<<<<<<<<<<<<<<<<<<<<<<<<<\n\t\tfor (String rk : rkset) {\n\t\t\tif (rk == null || KEY_STRING.equals(rk) || KEY_TRIM.equals(rk)) {\n\t\t\t\t// ConcurrentModificationException  real.remove(rk);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (refuseSet.contains(rk)) { // 不允许的字段\n\t\t\t\tthrow new IllegalArgumentException(method + \"请求，\" + name\n\t\t\t\t\t\t+ \" 里面不允许传 \" + rk + \" 等\" + StringUtil.get(refuseSet) + \"内的任何字段！\");\n\t\t\t}\n\n\t\t\tif (KEY_COMBINE.equals(rk)) {\n\t\t\t\tthrow new UnsupportedOperationException(method + \" 请求，\" + rk + \" 不合法！\" +\n\t\t\t\t\t\t\"非开放请求不允许传 \" + KEY_COMBINE + \":value ！\");\n\t\t\t}\n\t\t\tif (KEY_KEY.equals(rk)) {\n\t\t\t\tthrow new UnsupportedOperationException(method + \" 请求，\" + rk + \" 不合法！\" +\n\t\t\t\t\t\t\"非开放请求不允许传 \" + KEY_KEY + \":value ！\");\n\t\t\t}\n\n\t\t\tObject rv = real.get(rk);\n\t\t\tif (rv != null && stringKeyList != null && stringKeyList.contains(rk)) {\n\t\t\t\trv = toJSONString(rv);\n\t\t\t}\n\t\t\tif (rv != null && trimKeyList != null && trimKeyList.contains(rk)) {\n\t\t\t\trv = StringUtil.trim(rv);\n\t\t\t}\n\n\t\t\t// 不允许传远程函数，只能后端配置\n\t\t\tif (rk.endsWith(\"()\") && rv instanceof String) {\n\t\t\t\tthrow new UnsupportedOperationException(method + \" 请求，\" + rk + \" 不合法！\" +\n                        \"非开放请求不允许传远程函数 key():\\\"fun()\\\" ！\");\n\t\t\t}\n\n\t\t\t// 不在target内的 key:{}","sourceCodeStart":1108,"sourceCodeEnd":1144,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractVerifier.java#L1108-L1144","documentation":"Thrown when a non-open request carries the @key key (per-request table-key / primary-key selector). Like @combine, it is a query-shaping directive reserved for open requests; closed requests fix it in configuration.","triggerScenarios":"A request body containing \"@key\":\"userId\" sent to a tag whose Request-table row is not open.","commonSituations":"Frontend adds @key while trying to switch which column identifies rows (e.g. dedupe by userId instead of id) on a locked endpoint; pasting from APIJSON documentation examples.","solutions":["Drop @key from the payload","Have the backend set the intended key in the Request-table config or mark the request open","If you need per-request key selection, expose it via a dedicated open tag"],"exampleFix":"// before\n{\"User\":{\"name\":\"a\",\"@key\":\"userId\"}}\n// after\n{\"User\":{\"name\":\"a\"}}","handlingStrategy":"validation","validationCode":"function stripLockedKeys(obj) {\n  const out = { ...obj };\n  delete out['@key'];\n  return out;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat @key as server configuration, not a client parameter","Do not copy example bodies from docs into non-open endpoints"],"tags":["apijson","at-key","open-request","security"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}