Tencent/APIJSON · error · IllegalArgumentException

{} 内截至 {}:{} 时对象 key:{} 的数量达到 {} 已超限,必须在 0-{} 内 !

Error message

{} 内截至 {}:{} 时对象 key:{} 的数量达到 {} 已超限,必须在 0-{} 内 !

What it means

Companion DoS guard to the array limit: each object parser counts parsed table objects and enforces parser.getMaxObjectCount() (default AbstractParser.MAX_OBJECT_COUNT = 5). Thrown when the number of object keys exceeds the maximum, with current count and limit in the message. The comment in source notes a TODO to use maxUpdateCount for batch writes.

Source

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

					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) {
				invalidate();
			}
		}
//		Log.i(TAG, "onChildParse  ObjectParser.onParse  key = " + key + "; child = " + child);

		return isEmpty ? null : child; // 只添加! isChildEmpty的值,可能数据库返回数据不够count
	}

View on GitHub (pinned to 5284052872)

Solutions

  1. Reduce the number of tables per request — split into several requests or fetch associated data lazily.
  2. Raise the limit deliberately: override getMaxObjectCount() in your parser subclass or set AbstractParser.MAX_OBJECT_COUNT, understanding the query-explosion implications.
  3. For deep joins, verify each nesting level actually needs its own table object.

Example fix

// server: allow 10 tables per request
public class MyParser extends AbstractParser<Long> {
    @Override
    public int getMaxObjectCount() { return 10; }
}
Defensive patterns

Strategy: validation

Validate before calling

int objects = countTableObjects(request); // walk nested maps counting table-key entries
if (objects > 5) throw new IllegalArgumentException("too many table objects (" + objects + "), split the request");

Type guard

function countTables(o: unknown): number {
  if (o === null || typeof o !== 'object' || Array.isArray(o)) return 0;
  return Object.entries(o).reduce((n, [k, v]) => n + (v !== null && typeof v === 'object' && !k.endsWith('[]') ? 1 + countTables(v) : n), 0);
}
const withinObjectLimit = (req: object, max = 5) => countTables(req) <= max;

Prevention

When it happens

Trigger: A request object nesting more than 5 table objects (e.g. a deep join graph with 6+ tables, or 6 sibling table keys at one level).

Common situations: Complex multi-table queries / deep association chains; batch inserts referencing many tables in one request; sharing one parser config across endpoints with different complexity needs.

Related errors


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