Tencent/APIJSON · error · IllegalArgumentException
字符 ${method} 不合法!预编译模式下 @having:"column?value;function(arg0,
Error message
字符 ${method} 不合法!预编译模式下 @having:"column?value;function(arg0,arg1,...)?value..." 中 function 必须符合小写英文单词的 SQL 函数名格式! What it means
For a function call in @having, when the backend has no SQL_FUNCTION_MAP configured (null or empty) the fallback check StringUtil.isName(method) applies: the function name before '(' must be a plain identifier. Otherwise IllegalArgumentException. This is the lenient path — it validates shape but cannot whitelist.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java:1786
throw new UnsupportedOperationException("字符串 " + expression + " 不合法!"
+ "预编译模式下 @having:\"column?value;function(arg0,arg1,...)?value...\""
+ " 中 column?value 必须符合正则表达式 " + PATTERN_FUNCTION + " 且不包含连续减号 -- !不允许空格!");
}
return parseSQLExpression(KEY_HAVING, expression, containRaw, false, null);
}
int end = expression.lastIndexOf(")");
if (start >= end) {
throw new IllegalArgumentException("字符 " + expression + " 不合法!"
+ "@having:value 中 value 里的 SQL函数必须为 function(arg0,arg1,...) 这种格式!");
}
String method = expression.substring(0, start);
if (method.isEmpty() == false) {
if (SQL_FUNCTION_MAP == null || SQL_FUNCTION_MAP.isEmpty()) {
if (StringUtil.isName(method) == false) {
throw new IllegalArgumentException("字符 " + method + " 不合法!"
+ "预编译模式下 @having:\"column?value;function(arg0,arg1,...)?value...\""
+ " 中 function 必须符合小写英文单词的 SQL 函数名格式!");
}
}
else if (SQL_FUNCTION_MAP.containsKey(method) == false) {
throw new IllegalArgumentException("字符 " + method + " 不合法!"
+ "预编译模式下 @column:\"column0,column1:alias;function0(arg0,arg1,...);function1(...):alias...\""
+ " 中 function 必须符合小写英文单词的 SQL 函数名格式!且必须是后端允许调用的 SQL 函数!");
}
}
return method + parseSQLExpression(KEY_HAVING, expression.substring(start), containRaw, false, null);
}
@Override
public String getSample() {
return sample;
}View on GitHub (pinned to 5284052872)
Solutions
- Use a clean single-word function name: "@having": "max(amount)>10"
- Backend: configure SQL_FUNCTION_MAP so functions are whitelist-checked instead
- Avoid qualified/odd names; alias complex expressions via @raw
Example fix
// before
{"@having": "schema.max(amount)>10"}
// after
{"@having": "max(amount)>10"} Defensive patterns
Strategy: validation
Validate before calling
const fnName = hv.slice(0, hv.indexOf('('));
if (fnName && !/^[A-Za-z_][A-Za-z0-9_]*$/.test(fnName)) {
throw new Error(`@having function '${fnName}' must be a plain identifier when SQL_FUNCTION_MAP is unset`);
} Type guard
const isPlainFunctionName = s => /^[A-Za-z_][A-Za-z0-9_]*$/.test(s);
Try / catch
try { await api.get(req); } catch (e) { if (e.message.includes('SQL 函数名格式') && e.message.includes('@having')) suggestConfiguringFunctionMap(); else throw e; } Prevention
- Use unqualified function names (no schema. prefix)
- Configure SQL_FUNCTION_MAP in production so names are whitelisted, not just shape-checked
When it happens
Trigger: "@having": "ma x(1)>0" (space in name), "@having": "1max(a)>0" (starts with digit), "@having": "max-(a)>0" — the extracted method substring fails isName when SQL_FUNCTION_MAP is unset.
Common situations: Self-hosted APIJSON where SQL_FUNCTION_MAP was never populated; typos in function names producing stray characters; trying schema-qualified names like schema.func().
Related errors
- 字符 ${method} 不合法!预编译模式下 @column:"column0,column1:alias;funct
- @having:value 的 value 中字符串 ${expression} 不合法!不允许传超过 100 个字符的
- 字符串 ${expression} 不合法!预编译模式下 @having:"column?value;function(
- 字符 ${expression} 不合法!@having:value 中 value 里的 SQL函数必须为 funct
- @raw:value 的 value 中 {key} 不合法!对应的 {key}:value 中 value 值 {va
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/9a711a7e1ec4fd88.
Report an issue: GitHub.