{"record":{"id":"2a0892d71ddf6bc5","repo":"Tencent/APIJSON","slug":"abstractsqlconfig-getwhereitem","errorCode":null,"errorMessage":"AbstractSQLConfig.getWhereItem: 字符 {} 不合法！","messagePattern":"AbstractSQLConfig\\.getWhereItem: 字符 (.+?) 不合法！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java","lineNumber":3957,"sourceCode":"\n\t/**\n\t * @param key\n\t * @param value\n\t * @param method\n\t * @param verifyName\n\t * @return\n\t * @throws Exception\n\t */\n\tprotected String gainWhereItem(String key, Object value, RequestMethod method, boolean verifyName) throws Exception {\n\t\tLog.d(TAG, \"getWhereItem  key = \" + key);\n\t\t// 避免筛选到全部\tvalue = key == null ? null : where.get(key);\n\t\tif (key == null || key.endsWith(\"()\") || key.startsWith(\"@\")) { //关键字||方法, +或-直接报错\n\t\t\tLog.d(TAG, \"getWhereItem  key == null || key.endsWith(()) || key.startsWith(@) >> continue;\");\n\t\t\treturn null;\n\t\t}\n\t\tif (key.endsWith(\"@\")) { // 引用\n\t\t\t//\tkey = key.substring(0, key.lastIndexOf(\"@\"));\n\t\t\tthrow new IllegalArgumentException(TAG + \".getWhereItem: 字符 \" + key + \" 不合法！\");\n\t\t}\n\n\t\tif (value == null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tint keyType;\n\t\tif (key.endsWith(\"$\")) {\n\t\t\tkeyType = 1;\n\t\t}\n\t\telse if (key.endsWith(\"~\")) {\n\t\t\tkeyType = key.charAt(key.length() - 2) == '*' ? -2 : 2;  //FIXME StringIndexOutOfBoundsException\n\t\t}\n\t\telse if (key.endsWith(\"%\")) {\n\t\t\tkeyType = 3;\n\t\t}\n\t\telse if (key.endsWith(\"{}\")) {\n\t\t\tkeyType = 4;","sourceCodeStart":3939,"sourceCodeEnd":3975,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java#L3939-L3975","documentation":"Thrown by gainWhereItem when a condition key ends with '@'. Trailing '@' marks a reference (e.g. \"id@\": \"@/User/id\") and such keys must be resolved earlier by the parser, not passed through as a plain WHERE item; reaching this branch means the reference was left unresolved/malformed.","triggerScenarios":"Sending a condition like {\"User\": {\"myCol@\": \"@/other/id\"}} where the reference path is invalid or the parser could not associate it, leaving the raw key to fall into normal WHERE-item processing.","commonSituations":"Typos in reference paths, referencing a table/alias not present in the same request, or using '@' suffix accidentally as part of a column name.","solutions":["Fix the reference: \"key@\": \"@/Table/alias/column\" must point to a table and alias that exist in the same request.","If '@' was not intended as a reference, rename the key so it does not end with '@'.","Ensure the referenced table is inside the same request object graph, not a separate request."],"exampleFix":"// before\n{\"User\": {\"id@\": \"@/Comment/userIdx\"}, \"Comment\": {...}}\n// after\n{\"User\": {\"id@\": \"@/Comment/userId\"}, \"Comment\": {...}}","handlingStrategy":"validation","validationCode":"for (const key of Object.keys(tableObj)) {\n  if (key.endsWith('@')) {\n    const ref = tableObj[key]; // must be '@/Table/alias/col'\n    if (!/^\\/@?\\w+(\\/\\w+){1,2}$/.test(ref)) throw new Error('bad reference ' + key);\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate '@/Table/alias/column' reference paths client-side.","Never use '@' as the last character of a normal column key."],"tags":["apijson","reference","where-key","validation"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}