{"record":{"id":"d9803337da0cf895","repo":"Tencent/APIJSON","slug":"key-value-value-sc","errorCode":null,"errorMessage":"{}: { @key(): value } 对应存储过程 value 中字符 `{} 不合法！`schema` 当有 ` 包裹时一定是首尾各一个，不能多也不能少！","messagePattern":"(.+?): (.+?) 对应存储过程 value 中字符 `(.+?) 不合法！`schema` 当有 ` 包裹时一定是首尾各一个，不能多也不能少！","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java","lineNumber":709,"sourceCode":"\tpublic static String extractSchema(String sch, String table) {\n\t\tif (StringUtil.isEmpty(sch)) {\n\t\t\treturn sch;\n\t\t}\n\n\t\tif (table == null) {\n\t\t\ttable = \"Table\";\n\t\t}\n\n\t\tint ind = sch.indexOf(\"`\");\n\t\tif (ind > 0) {\n\t\t\tthrow new IllegalArgumentException(table + \": { @key(): value } 对应存储过程 value 中字符 \"\n\t\t\t\t\t+ sch + \" 不合法！`schema` 当有 ` 包裹时一定是首尾各一个，不能多也不能少！\");\n\t\t}\n\n\t\tif (ind == 0) {\n\t\t\tsch = sch.substring(1);\n\t\t\tif (sch.indexOf(\"`\") != sch.length() - 1) {\n\t\t\t\tthrow new IllegalArgumentException(table + \": { @key(): value } 对应存储过程 value 中字符 `\"\n\t\t\t\t\t\t+ sch + \" 不合法！`schema` 当有 ` 包裹时一定是首尾各一个，不能多也不能少！\");\n\t\t\t}\n\n\t\t\tsch = sch.substring(0, sch.length() - 1);\n\t\t}\n\n\t\tif (PATTERN_SCHEMA.matcher(sch).matches() == false || sch.contains(\"--\")) {\n\t\t\tthrow new IllegalArgumentException(table + \": { @key(): value } 对应存储过程 value 中字符 \"\n\t\t\t\t\t+ sch + \" 不合法！schema.function(arg) 中 schema 必须符合 数据库名/模式名 的命名规则！\"\n\t\t\t\t\t+ \"一般只能传英文字母、数字、下划线！不允许 -- 等可能导致 SQL 注入的符号！\");\n\t\t}\n\n\t\treturn sch;\n\t}\n\n\n\t/**\n\t * @param method","sourceCodeStart":691,"sourceCodeEnd":727,"githubUrl":"https://github.com/Tencent/APIJSON/blob/5284052872898eddc449a58f629e5c8d588b8e22/APIJSONORM/src/main/java/apijson/orm/AbstractFunctionParser.java#L691-L727","documentation":"extractSchema() backtick-pair branch: when the schema starts with a backtick, after stripping that first character the remaining string must have its last backtick exactly at the final position (i.e. exactly one closing backtick at the end). This throw fires when the schema begins with '`' but has no matching sole closing backtick at the end — e.g. '`schema' or '`sch`ema' — so the wrapper is unbalanced and the identifier is rejected.","triggerScenarios":"Stored procedure value strings such as '`mydb.func(id)' (missing closing backtick), '`my`db.func(id)' (extra backtick in the middle), or '`mydb`.x' variants where the second backtick is not terminal.","commonSituations":"Hand-typing quoted schema names and forgetting the closing '`'; string concatenation in front-end code dropping the trailing character; templating that collapses '``' into '`'.","solutions":["Make the backtick wrapper symmetric: start with '`' and end with '`' with none in between: '`mydb`.my_proc(id)'.","Prefer omitting backticks entirely for identifiers that only use letters, digits and underscores.","Add a client-side check that the schema segment matches ^`?[A-Za-z0-9_]+`?$ before sending."],"exampleFix":"// before\n\"@procedure()\": \"`mydb.my_proc(id)\"\n// after\n\"@procedure()\": \"`mydb`.my_proc(id)\"","handlingStrategy":"validation","validationCode":"boolean balancedBackticks(String sch) {\n  if (!sch.startsWith(\"`\")) return sch.indexOf('`') < 0;\n  return sch.length() > 1 && sch.endsWith(\"`\") && sch.indexOf('`', 1) == sch.length() - 1;\n}","typeGuard":"function hasBalancedBackticks(s: string): boolean {\n  if (!s.startsWith('`')) return !s.includes('`');\n  return s.length > 1 && s.endsWith('`') && s.indexOf('`', 1) === s.length - 1;\n}","tryCatchPattern":null,"preventionTips":["Never hand-type backticks; build the schema string with a helper that adds the pair atomically.","Check for an odd number of backticks before sending.","Avoid schema names that themselves contain backticks."],"tags":["apijson","stored-procedure","schema","backtick","validation"],"backgroundTag":null,"analyzedSha":"5284052872898eddc449a58f629e5c8d588b8e22","analyzedAt":"2026-08-14T15:15:29.577Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}