Tencent/APIJSON · error · IllegalArgumentException
originKey + ":value 中字符 " + originKey + " 不合法!key$:value 中不允
Error message
originKey + ":value 中字符 " + originKey + " 不合法!key$:value 中不允许只有单独的 '?',必须和 '%', '_' 之一配合使用 !
What it means
In the same '$' (LIKE) placeholder parsing: '?' means 'use the value as-is at this position' and only makes sense combined with '%' or '_' (key?%$ → LIKE 'v%', key_?$ → LIKE '_v'). A key ending with just '?$', i.e. a lone '?' with no % or _ companion, throws IllegalArgumentException because '?value' alone would produce a malformed/pointless LIKE pattern.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/Join.java:307
k = originKey.substring(0, originKey.length() - 1);
char c = k.isEmpty() ? 0 : k.charAt(k.length() - 1);
String t = "$";
if (c == '%' || c == '_' || c == '?') {
t = c + t;
k = k.substring(0, k.length() - 1);
char c2 = k.isEmpty() ? 0 : k.charAt(k.length() - 1);
if (c2 == '%' || c2 == '_' || c2 == '?') {
if (c2 == c) {
throw new IllegalArgumentException(originKey + ":value 中字符 " + k + " 不合法!key$:value 中不允许 key 中有连续相同的占位符!");
}
t = c2 + t;
k = k.substring(0, k.length() - 1);
}
else if (c == '?') {
throw new IllegalArgumentException(originKey + ":value 中字符 " + originKey + " 不合法!key$:value 中不允许只有单独的 '?',必须和 '%', '_' 之一配合使用 !");
}
}
setRelateType(t);
}
else if (originKey.endsWith("~")) {
boolean ignoreCase = originKey.endsWith("*~");
setRelateType(ignoreCase ? "*~" : "~");
k = originKey.substring(0, originKey.length() - (ignoreCase ? 2 : 1));
}
else if (originKey.endsWith(">=")) {
setRelateType(">=");
k = originKey.substring(0, originKey.length() - 2);
}
else if (originKey.endsWith("<=")) {
setRelateType("<=");
k = originKey.substring(0, originKey.length() - 2);
}View on GitHub (pinned to 5284052872)
Solutions
- Use the default containment form with no placeholder: "name$":"a" → LIKE '%a%'.
- Combine '?' with % or _: "name?%$":"a" → LIKE 'a%', "name_?$":"a" → LIKE '_a'.
- For a literal '?' in a pattern, include it in the value string instead of the key.
Example fix
// before
"User":{"name?$":"Tom"} // lone '?', rejected
// after
"User":{"name$":"Tom"} // LIKE '%Tom%'
// or
"User":{"name?%$":"Tom"} // LIKE 'Tom%' Defensive patterns
Strategy: validation
Validate before calling
function assertLikeJoinKey(k) {
if (/[?]\$$/.test(k) && !/[%_][?]\$$|[?][%_]\$$/.test(k))
throw new Error("lone '?' in '" + k + "' — combine with % or _ (key?%$, key_?$) or drop it (key$)");
} Type guard
function isLikeJoinKey(k) { return !/\?\$$/.test(k) || /[%_]\?\$|\?[%_]\$/.test(k); } Prevention
- Learn the placeholder semantics: '?' = insert value verbatim here, '%'/'_' = SQL wildcards; '?' never stands alone.
- Default to plain key$ (LIKE '%v%') unless you truly need anchored patterns.
When it happens
Trigger: Join table object contains e.g. "name?$":"a" or "status?$":"x" — after stripping the trailing '?', the next char back is neither '%', '_', nor '?' (c == '?' and no c2 companion), so the else-if branch throws.
Common situations: Assuming '?' is a single-char wildcard like SQL '_' — in APIJSON '?' is an exact-position marker, not a wildcard; typo when aiming for 'key_?$'; forgetting that plain containment already is the default (key$ → LIKE '%v%') so no placeholder is needed at all.
Related errors
- originKey + ":value 中字符 " + k + " 不合法!key$:value 中不允许 key 中有
- joinType + "/.../" + table + "/" + originKey + " 中字符 " + ori
- joinType + "/.../" + table + "/" + originKey + " 中字符 " + k +
- joinType + "/.../" + table + "/" + originKey + " 中字符 " + l.g
- 字符 {} 不合法!远程函数不允许指定类名!且必须为 function(key0,key1,...) 这种单函数格式!\
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/0e2dabc8a99f36ff.
Report an issue: GitHub.