Tencent/APIJSON · error · IllegalArgumentException

join:'${e.getKey()}' 对应的 ${arrKey}:{ join: value } 中 value 不

Error message

join:'${e.getKey()}' 对应的 ${arrKey}:{ join: value } 中 value 不合法!@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中不能有 join: value 键值对!

What it means

For @ APP JOIN targeting a sub-array (arrKey present), the sub-array's object must NOT itself contain a join key and its page must be null/0. If parentPathObj.get("join") is non-null, IllegalArgumentException is thrown: APP JOIN may span only one level and cannot nest further join definitions.

Source

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

			// 取出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) {
					throw new NullPointerException("tableObj == null");
				}
			}
			catch (Exception e2) {
				throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + tableKey + ":value 中 value 类型不合法!" +
          			"必须是 {} 这种 Map<String, Object> 格式!" + e2.getMessage());
			}

			if (arrKey != null) {
				if (parentPathObj.get(apijson.JSONRequest.KEY_JOIN) != null) {
					throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ join: value } 中 value 不合法!" +
							"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中不能有 join: value 键值对!");
				}

				Integer subPage = getInteger(parentPathObj, apijson.JSONRequest.KEY_PAGE);
				if (subPage != null && subPage != 0) {
					throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":'" + e.getKey() + "' 对应的 " + arrKey + ":{ page: value } 中 value 不合法!" +
							"@ APP JOIN 最多允许跨 1 层,只能是子数组,且数组对象中 page 值只能为 null 或 0 !");
				}
			}

			boolean isAppJoin = "@".equals(joinType);

			M refObj = JSON.createJSONObject();

			String key = index < 0 ? null : path.substring(index + 1); // id@
			if (key != null) {  // 指定某个 key 为 JOIN ON 条件
				if (key.indexOf("@") != key.length() - 1) {
					throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":" + e.getKey() + " 中 " + key + " 不合法!"

View on GitHub (pinned to 5284052872)

Solutions

  1. Remove the inner join key from the sub-array object; move needed joins to the top level or use SQL join types
  2. Set the sub-array's page to 0 or remove it entirely
  3. Restructure: perform the nested join as a separate request and stitch results by reference
  4. Reserve @ APP JOIN for the simple one-level fan-out case

Example fix

// before
{"@join":"@/list[]/User","list[]":{"join":"&/Tag","page":1,"User":{}}}
// after
{"@join":"@/list[]/User","list[]":{"User":{}}}
Defensive patterns

Strategy: validation

Validate before calling

Map<?,?> arrObj = (Map<?,?>) root.get(arrKey);
if (arrObj != null && arrObj.get("join") != null) throw new IllegalStateException("app-join sub-array must not contain join");
if (arrObj != null && Integer.valueOf(0).equals(arrObj.get("page")) == false && arrObj.get("page") != null) throw new IllegalStateException("page must be 0");

Type guard

boolean subArrayCleanForAppJoin(Map<?,?> arrObj) {
  return arrObj != null && arrObj.get("join") == null && (arrObj.get("page") == null || Integer.valueOf(0).equals(arrObj.get("page")));}

Prevention

When it happens

Trigger: {"@join":"@/list[]/User", "list[]":{"join":"&/X", ...}} — an inner join inside the array object being app-joined. The sibling page check (next lines) similarly rejects page!=0 because app-join fetches must be single-page.

Common situations: Composing query builders that merge join clauses into every level; converting an SQL multi-join request to APP JOIN by only flipping sigils; UI presets injecting default page values into every nested array.

Related errors


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