Tencent/APIJSON · error · IllegalArgumentException

{}/{}:{} 不合法!数组 []:{} 中每个 key:{} 都必须是表 TableKey:{} 或 数组 arra

Error message

{}/{}:{} 不合法!数组 []:{} 中每个 key:{} 都必须是表 TableKey:{} 或 数组 arrayKey[]:{} !

What it means

Within an array item context (type == TYPE_ITEM), every non-array key must be a table key ('TableKey':{}). When a child key of an array item is neither an array key (handled above) nor a valid table key per JSONMap.isTableKey (after Pair.parseEntry strips alias), this IllegalArgumentException is thrown — non-table keys like 'total', 'info' or arbitrary names are not allowed directly inside '[]'.

Source

Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractObjectParser.java:641

				String infoKey = JSONResponse.formatArrayKey(key) + "Info";
				if ((request.containsKey(totalKey) || request.containsKey(infoKey)
						|| request.containsKey(totalKey + "@") || request.containsKey(infoKey + "@")) == false) {
					// onParse("total@", "/" + key + "/total");
					// onParse(infoKey + "@", "/" + key + "/info");
					// 替换为以下性能更好、对流程干扰最小的方式:

					String keyPath = AbstractParser.getValuePath(type == TYPE_ITEM ? path : parentPath, "/" + key);
					String totalPath = keyPath + "/total";
					String infoPath = keyPath + "/info";
					response.put(totalKey, onReferenceParse(totalPath));
					response.put(infoKey, onReferenceParse(infoPath));
				}
			}
		}
		else { //APIJSON Object
			boolean isTableKey = JSONMap.isTableKey(Pair.parseEntry(key, true).getKey());
			if (type == TYPE_ITEM && isTableKey == false) {
				throw new IllegalArgumentException(parentPath + "/" + key + ":{} 不合法!"
						+ "数组 []:{} 中每个 key:{} 都必须是表 TableKey:{} 或 数组 arrayKey[]:{} !");
			}

			if ( //避免使用 "test":{"Test":{}} 绕过限制,实现查询爆炸   isTableKey &&
					(arrayConfig == null || arrayConfig.getPosition() == 0)) {
				objectCount ++;
				int maxObjectCount = parser.getMaxObjectCount();
				if (objectCount > maxObjectCount) {  //TODO 这里判断是批量新增/修改,然后上限为 maxUpdateCount
					throw new IllegalArgumentException(path + " 内截至 " + key + ":{} 时对象"
							+ " key:{} 的数量达到 " + objectCount + " 已超限,必须在 0-" + maxObjectCount + " 内 !");
				}
			}

			child = parser.onObjectParse(value, path, key, isMain ? arrayConfig.setType(SQLConfig.TYPE_ITEM_CHILD_0) : null
					, isSubquery, cache instanceof Map<?, ?> ? (M) cache : null);

			isEmpty = child == null || ((Map<?, ?>) child).isEmpty();
			if (isFirst && isEmpty) {

View on GitHub (pinned to 5284052872)

Solutions

  1. Move non-table keys out of '[]' to the enclosing object: { "[]": { "User": {} }, "total": 3 }.
  2. Ensure every key inside the array item is a valid table key (or a nested 'key[]' array).
  3. Use 'query': 2 on the array to get total/info instead of adding them by hand.

Example fix

// before
{ "[]": { "User": { "sex": 1 }, "total": 3 } }
// after
{ "[]": { "User": { "sex": 1 } }, "query": 2 }
Defensive patterns

Strategy: validation

Validate before calling

for (String k : arrayItemRequest.keySet()) {
  if (!k.endsWith("[]") && !JSONMap.isTableKey(Pair.parseEntry(k, true).getKey())) {
    throw new IllegalArgumentException(k + " inside [] must be a TableKey or arrayKey[]");
  }
}

Type guard

const TABLE_KEY = /^[A-Za-z][A-Za-z0-9_]*$/; // adjust to your table naming rule
function arrayChildKeysValid(keys: string[]): boolean {
  return keys.every(k => k.endsWith('[]') || TABLE_KEY.test(k));
}

Prevention

When it happens

Trigger: "[]": { "User": { ... }, "total": 3 } — placing a plain key such as 'total', 'tag' or 'My alias':{} (unparseable/invalid table key) directly inside the array item template.

Common situations: Adding pagination hints or metadata inside '[]' instead of beside it; using keys starting with lowercase or containing characters that fail isTableKey; forgetting that only table objects may sit at array-item level.

Related errors


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