Tencent/APIJSON · error · IllegalArgumentException
{}/{}:value 中 value 必须为函数String!
Error message
{}/{}:value 中 value 必须为函数String! What it means
Any key ending in '()' designates a remote function call and its value must be a String in the form function(key0,key1,...). This IllegalArgumentException fires when the value is not a String — e.g. a JSONObject, JSONArray, number or boolean.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java:540
// Log.d(TAG, "onParse isTable(table) == false >> return true;");
// return true;//舍去,对Table无影响
// }
// }
// 直接替换原来的 key@: path 为 key: target
Log.i(TAG, "onParse >> key = replaceKey; value = target;");
key = replaceKey;
value = target;
Log.d(TAG, "onParse key = " + key + "; value = " + value);
}
else {
throw new IllegalArgumentException(path + "/" + key + ":value 中 value 必须为 依赖路径String 或 SQL子查询JSONObject !");
}
}
if (key.endsWith("()")) {
if (value instanceof String == false) {
throw new IllegalArgumentException(path + "/" + key + ":value 中 value 必须为函数String!");
}
String k = key.substring(0, key.length() - 2);
String type; //远程函数比较少用,一般一个Table:{}内用到也就一两个,所以这里用 "-","0","+" 更直观,转用 -1,0,1 对性能提升不大。
boolean isMinus = k.endsWith("-");
boolean isPlus = isMinus == false && k.endsWith("+");
if (isMinus) { //不能封装到functionMap后批量执行,否则会导致非Table内的 key-():function() 在onChildParse后执行!
type = "-";
k = k.substring(0, k.length() - 1);
}
else if (isPlus) {
type = "+";
k = k.substring(0, k.length() - 1);
}
else {
type = "0";
}View on GitHub (pinned to 5284052872)
Solutions
- Provide the value as a String: "key()": "functionName(argKey)".
- Keep arguments as request keys referenced inside the parentheses, not as nested JSON.
Example fix
// before
"tagList()": { "getTags": "id" }
// after
"tagList()": "getTags(id)" Defensive patterns
Strategy: type-guard
Validate before calling
for (String k : request.keySet()) {
String base = k.endsWith("()") ? k : (k.endsWith("-()") || k.endsWith("+()")) ? k.substring(0, k.length() - 3) + "()" : null;
if (base != null && !(request.get(k) instanceof String)) throw new IllegalArgumentException(k + " must map to a function String");
} Type guard
function isFunctionStringValue(key: string, v: unknown): boolean {
return !/^(.*[-+])?\(\)$/.test(key) || typeof v === 'string';
} Prevention
- Always write 'key()': "fn(argKey)" — value is a String.
- Don't build function calls as nested JSON objects.
- Remember 'key-()' / 'key+()' variants carry the same String requirement.
When it happens
Trigger: "name()": { "fun": "arg" } or "name()": 123. Any 'key()' entry whose value fails instanceof String, including 'key-()' / 'key+()' variants since the check runs after the suffix marker is stripped.
Common situations: Client builds the function call as structured JSON instead of a string; copy-paste replaces the quotes; confusion between 'key@' object form and 'key()' string form.
Related errors
- 字符 {} 不合法!远程函数不允许指定类名!且必须为 function(key0,key1,...) 这种单函数格式!\
- 字符 " + function + " 不合法!
- 子查询 {}/{}:{ range:value } 中 value 只能为 [ALL, ANY] 中的一个!
- 子查询 {}/{}:{ from:value } 中 value 对应的主表对象 {}:{} 不存在!
- {}/{}:value 中 value 必须为 依赖路径String 或 SQL子查询JSONObject !
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/58d92d02a9bf76f0.
Report an issue: GitHub.