Tencent/APIJSON · error · IllegalArgumentException

@join:value 中 value 的 Table 值 {} 不合法!必须为 &/Table0,</Table1/k

Error message

@join:value 中 value 的 Table 值 {} 不合法!必须为 &/Table0,</Table1/key1,@/Table1:alias2/key2,... 或 { '&/Table0':{}, '</Table1/key1':{},... } 这种格式!且 Table 必须满足大写字母开头的表对象英文单词 key 格式!

What it means

After splitting the join path, the table segment is parsed (Table:alias) and validated with StringUtil.isName — must be a valid identifier word (and by APIJSON convention an uppercase-initial table object name). Failure throws IllegalArgumentException showing the offending table and the full expected grammar.

Source

Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractParser.java:1639

			//				joinType = "|"; // FULL JOIN
			//			}
			path = path.substring(index + 1);

			index = path.lastIndexOf("/");
			String tableKey = index < 0 ? path : path.substring(0, index); // User:owner
			int index2 = tableKey.lastIndexOf("/");
			String arrKey = index2 < 0 ? null : tableKey.substring(0, index2);
			if (arrKey != null && isArrayKey(arrKey) == false) {
				throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + " 不是合法的数组 key[] !" +
						"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中不能有 join: value 键值对!");
			}

			tableKey = index2 < 0 ? tableKey : tableKey.substring(index2+1);

			apijson.orm.Entry<String, String> entry = Pair.parseEntry(tableKey, true);
			String table = entry.getKey(); // User
			if (StringUtil.isName(table) == false) {
				throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":value 中 value 的 Table 值 " + table + " 不合法!"
						+ "必须为 &/Table0,</Table1/key1,@/Table1:alias2/key2,... 或 { '&/Table0':{}, '</Table1/key1':{},... } 这种格式!"
						+ "且 Table 必须满足大写字母开头的表对象英文单词 key 格式!");
			}

			String alias = entry.getValue(); // owner
			if (StringUtil.isNotEmpty(alias, true) && StringUtil.isName(alias) == false) {
				throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":value 中 value 的 alias 值 " + alias + " 不合法!"
						+ "必须为 &/Table0,</Table1/key1,@/Table1:alias2/key2,... 或 { '&/Table0':{}, '</Table1/key1':{},... } 这种格式!"
						+ "且 Table:alias 的 alias 必须满足英文单词变量名格式!");
			}

			// 取出Table对应的JSONObject,及内部引用赋值 key:value
			M tableObj;
			M parentPathObj;	// 保留
			try {
				parentPathObj = arrKey == null ? request : JSON.get(request, arrKey);	// 保留
				tableObj = parentPathObj == null ? null : JSON.get(parentPathObj, tableKey);
				if (tableObj == null) {

View on GitHub (pinned to 5284052872)

Solutions

  1. Use the APIJSON table-object key spelling (uppercase first letter, word characters only), e.g. '&/User/id'
  2. If your table name is unconventional, map it via the table rename/alias config rather than the raw name
  3. Never build @join from unescaped user input; whitelist table names server-side
  4. Keep alias in the Table:alias slot, not glued into the table token

Example fix

// before
{"@join":"&/sys_user/id"}
// after
{"@join":"&/SysUser/id"}
Defensive patterns

Strategy: validation

Validate before calling

if (!table.matches("^[A-Z][A-Za-z0-9_]*$")) throw new IllegalArgumentException("bad join table: " + table);

Type guard

boolean isValidJoinTable(String t) { return t != null && t.matches("^[A-Z][A-Za-z0-9_]*$"); }

Prevention

When it happens

Trigger: "@join":"&/user/id" (lowercase start), table with digits at start, dashes, spaces, or SQL characters: '&/User-2/id', '@/u ser/x'. Any table token failing isName, including attempts to inject SQL through the table slot.

Common situations: Using actual DB table names that are lowercase or contain underscores where the ORM expects the camel/uppercase object key; SQL injection attempts via @join (this check is the guard); renaming tables without updating joins.

Related errors


AI-assisted analysis of Tencent/APIJSON@5284052872 (2026-08-14). Data as JSON: /api/errors/356820b74011bc05. Report an issue: GitHub.