Tencent/APIJSON · error · IllegalArgumentException
joinType + "/.../" + table + "/" + originKey + " 中字符 " + l.g
Error message
joinType + "/.../" + table + "/" + originKey + " 中字符 " + l.getKey() + " 不合法!必须符合字段命名格式!
What it means
Final join-key validation: after stripping operators and the optional '!' logic prefix (new Logic(k)), the bare field name must pass StringUtil.isName — i.e. start with a letter and contain only letters/digits/underscores (a valid identifier). Keys with spaces, dots, dashes, leading digits, or non-ASCII characters throw IllegalArgumentException, because the name will be interpolated into generated SQL as a column identifier.
Source
Thrown at APIJSONORM/src/main/java/apijson/orm/Join.java:349
setRelateType("<");
k = originKey.substring(0, originKey.length() - 1);
}
else {
setRelateType("");
k = originKey;
}
if (k != null && (k.contains("&") || k.contains("|"))) {
throw new UnsupportedOperationException(joinType + "/.../" + table + "/" + originKey + " 中字符 " + k + " 不合法!与或非逻辑符仅支持 '!' 非逻辑符 !");
}
//TODO if (c3 == '-') { // 表示 key 和 value 顺序反过来: value LIKE key
Logic l = new Logic(k);
setLogic(l);
if (StringUtil.isName(l.getKey()) == false) {
throw new IllegalArgumentException(joinType + "/.../" + table + "/" + originKey + " 中字符 " + l.getKey() + " 不合法!必须符合字段命名格式!");
}
setKey(l.getKey());
}
}
}
View on GitHub (pinned to 5284052872)
Solutions
- Use plain identifiers in join keys: letters, digits, underscore, starting with a letter — e.g. "userId@":"/Moment/userId".
- Move qualifying prefixes into the reference path (the '/table/field@' part), not the key: "id@":"/Moment/userId".
- If the actual DB column contains special chars, alias it in the structure config (@column) rather than in the join key; sanitize any programmatically generated keys with a ^[A-Za-z][A-Za-z0-9_]*$ check.
Example fix
// before
"User":{"user.id@":"/Moment/userId"}
// after
"User":{"id@":"/Moment/userId"} Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern NAME = Pattern.compile("^[A-Za-z][A-Za-z0-9_]*$");
String bareKeyAfterOperators(String k) { return k.replaceFirst("(\\{\\}|\\[\\]|<>|\\$|\\*?~|>=|<=|>|<|!)", ""); }
void assertJoinKeyIsName(String k) {
String bare = bareKeyAfterOperators(k);
if (!NAME.matcher(bare).matches())
throw new IllegalArgumentException("join key '" + k + "' reduces to '" + bare + "' which is not a valid identifier");
} Type guard
function isJoinKeyName(k) { return /^[A-Za-z][A-Za-z0-9_]*$/.test(k.replace(/[\{\}\[\]<>$~%_?>=!*]+$/, '')); } Prevention
- Join keys must be plain identifiers (letter first, then letters/digits/underscore) — no dots, dashes, spaces, or backticks.
- Put table qualification in the reference path ('/Moment/userId@'), never in the key.
- Sanitize any join config built from user input with a ^[A-Za-z][A-Za-z0-9_]*$ check before sending.
When it happens
Trigger: A join reference key like "user.id@" (dot), "my-name@" (dash), "1id@" (leading digit), or "名字@" (non-ASCII) after operator stripping leaves l.getKey() failing StringUtil.isName, e.g. from ORM joins. Also fires when only operators remain (empty key after stripping) or a key consists solely of placeholders.
Common situations: Using JSON-path style 'user.id' in join keys; column aliases with dashes leaking into keys; generating join config from user input without identifier validation; using SQL-quoted identifiers ("`col`") in key names.
Related errors
- @join:value 中 value 的 Table 值 {} 不合法!必须为 &/Table0,</Table1/k
- join:value 中 value 的 alias 值 ${alias} 不合法!必须为 &/Table0,</Tab
- joinType + "/.../" + table + "/" + originKey + " 中字符 " + ori
- originKey + ":value 中字符 " + k + " 不合法!key$:value 中不允许 key 中有
- originKey + ":value 中字符 " + originKey + " 不合法!key$:value 中不允
AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14).
Data as JSON: /api/errors/9c73625b2c9a7917.
Report an issue: GitHub.