Tencent/APIJSON · error · IllegalArgumentException

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

Error message

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

What it means

Thrown while parsing an APP JOIN ('@/Table/key' join type) whose joined table lives inside an array wrapper (arrKey). APP JOIN is executed in application memory across at most one array level, so the wrapper object's 'page' value must be null or 0; any other page number triggers this IllegalArgumentException because server-side pagination of an APP JOIN sub-array is not supported.

Source

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

				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 + " 不合法!"
							+ "必须为 &/Table0,</Table1/key1,@/Table1:alias2/key2,... 或 { '&/Table0':{}, '</Table1/key1':{},... } 这种格式!"
							+ "且 Table:alias 的 alias 必须满足英文单词变量名格式!");
				}

				if (tableObj.get(key) instanceof String == false) {
					throw new IllegalArgumentException(apijson.JSONRequest.KEY_JOIN + ":" + e.getKey() + "' 对应的 "

View on GitHub (pinned to 5284052872)

Solutions

  1. Delete the 'page' key (or set it to 0/null) inside the array object that contains the APP JOIN table
  2. Paginate the joined sub-array client-side after the response returns
  3. If server-side pagination of the child is required, split into two requests: page the main array with a normal SQL JOIN ('</Table/key@', '&/Table/key@') or query the child table separately

Example fix

// before
{
  'User[]': { 'page': 2, 'count': 10, 'User': {}, 'Comment': {} },
  'join': '@/User[]/Comment/toId@'
}
// after
{
  'User[]': { 'page': 2, 'count': 10, 'User': {}, 'Comment': {} },  // page on User[] ok if join path targets User[] level... remove page from the array that hosts the join
  'join': '@/User[]/Comment/toId@'
}
// simplest: drop page from the wrapper object referenced by the join path
Defensive patterns

Strategy: validation

Validate before calling

function checkAppJoinPage(request) {
  const joins = request.join;
  if (!joins) return null;
  const paths = typeof joins === 'string' ? [joins] : Object.keys(joins);
  for (const p of paths) {
    const m = p.match(/^@\/([\w\[\]]+)\//); // '@/arrKey/Table/key@'
    if (m && m[1].endsWith('[]')) {
      const arr = request[m[1]];
      if (arr && arr.page != null && arr.page !== 0) {
        return `join ${p}: ${m[1]}.page must be 0/null, got ${arr.page}`;
      }
    }
  }
  return null;
}

Try / catch

try { parser.parse(request); } catch (e) { if (e instanceof IllegalArgumentException && e.getMessage().contains('page 值只能为 null 或 0')) { /* strip page and re-issue */ } else throw e; }

Prevention

When it happens

Trigger: A request like { 'User[]': { 'page': 2, 'User': {...}, 'Comment': {...} }, 'join': '@/User[]/Comment/toId@' } — the array object User[] that hosts the joined table carries page: 1 or higher (page: 0 and absent page are fine).

Common situations: Copying a paginated multi-level array query and just changing the join type to '@'; migrating a list page that paginated both parent and child arrays; upgrading from a version where this was silently ignored.

Related errors


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