{"record":{"id":"12f27fda911e0062","repo":"Tencent/APIJSON","slug":"raw-value-value-value","errorCode":null,"errorMessage":"@raw:value 的 value 中 {} 不合法！对应的 {}: value 在当前对象 {} 不存在或 value = null，无法有效转为原始 SQL 片段！","messagePattern":"@raw:value 的 value 中 (.+?) 不合法！对应的 (.+?): value 在当前对象 (.+?) 不存在或 value = null，无法有效转为原始 SQL 片段！","errorType":"validation","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java","lineNumber":949,"sourceCode":"\n\n\t@Override\n\tpublic SQLConfig<T, M, L> newSQLConfig(boolean isProcedure) throws Exception {\n\t\tString raw = Log.DEBUG == false || sqlRequest == null ? null : getString(sqlRequest, JSONMap.KEY_RAW);\n\t\tString[] keys = raw == null ? null : StringUtil.split(raw);\n\t\tif (keys != null && keys.length > 0) {\n\t\t\tboolean allow = AbstractSQLConfig.ALLOW_MISSING_KEY_4_COMBINE;\n\n\t\t\tfor (String key : keys) {\n\t\t\t\tif (sqlRequest.get(key) != null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tString msg = \"@raw:value 的 value 中 \" + key + \" 不合法！对应的 \"\n\t\t\t\t\t\t+ key + \": value 在当前对象 \" + name + \" 不存在或 value = null，无法有效转为原始 SQL 片段！\";\n\n\t\t\t\tif (allow == false) {\n\t\t\t\t\tthrow new UnsupportedOperationException(msg);\n\t\t\t\t}\n\n\t\t\t\tif (parser instanceof AbstractParser) {\n\t\t\t\t\t((AbstractParser) parser).putWarnIfNeed(JSONMap.KEY_RAW, msg);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn newSQLConfig(method, table, alias, sqlRequest, joinList, isProcedure)\n\t\t\t\t.setParser(parser)\n\t\t\t\t.setObjectParser(this);\n\t}\n\n\t/**SQL 配置，for single object\n\t * @return {@link #setSQLConfig(int, int, int)}\n\t * @throws Exception\n\t */","sourceCodeStart":931,"sourceCodeEnd":967,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java#L931-L967","documentation":"@raw:\"key1,key2\" tells the parser to inline those keys' values as raw SQL fragments. Before building the SQLConfig, each referenced key is looked up in the current object (sqlRequest); if the value is missing or null, the key cannot be converted to a SQL fragment and UnsupportedOperationException is thrown (unless ALLOW_MISSING_KEY_4_COMBINE allows it, in which case only a warning is recorded).","triggerScenarios":"A request object containing \"@raw\":\"expr\" where the sibling key \"expr\" is absent or null, e.g. {\"@raw\":\"fn\",\"fn\":null}. Also when the key name in @raw has a typo or whitespace so it does not match any sibling key.","commonSituations":"Building function expressions (e.g. \"@raw\":\"func\",\"func\":\"reverse(name)\") and forgetting the companion value key; conditionally omitting the value key client-side when its expression is unavailable; renaming keys without updating the @raw list; relying on server-side defaults that leave the key null.","solutions":["Add the missing key with a non-null raw SQL fragment value next to @raw in the same object","Check exact spelling/case of every key listed in @raw against the sibling keys","If a key may legitimately be absent, either remove it from @raw or enable AbstractSQLConfig.ALLOW_MISSING_KEY_4_COMBINE (accepting the warning path)","Never rely on nested paths — @raw keys must exist in the current object only"],"exampleFix":"// before\n{\"User\":{\"@raw\":\"cond\"}}\n// after\n{\"User\":{\"@raw\":\"cond\",\"cond\":\"`age` > 18\"}}","handlingStrategy":"validation","validationCode":"String[] keys = rawList.split(\",\");\nfor (String k : keys) {\n  if (obj.get(k.trim()) == null) throw new IllegalStateException(\"@raw key missing value: \" + k);\n}","typeGuard":"boolean rawKeysAllPresent(Map<String,Object> obj, String rawSpec) {\n  return Arrays.stream(rawSpec.split(\",\")).allMatch(k -> obj.get(k.trim()) != null);\n}","tryCatchPattern":null,"preventionTips":["Generate @raw and its value keys from one builder variable so they cannot diverge","Unit-test each raw fragment expression against a real DB in CI","Treat @raw as SQL injection surface: whitelist fragments server-side"],"tags":["apijson","raw-sql","missing-key","validation","security"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}