Tencent/APIJSON · error · IllegalArgumentException

{errPrefix} 中字符 '{s}' 不合法!其中 key 数量 {allCount} 已超过最大值,必须在条件键

Error message

{errPrefix} 中字符 '{s}' 不合法!其中 key 数量 {allCount} 已超过最大值,必须在条件键值对数量 0-{maxCombineCount} 内!

What it means

A counter guard inside @combine parsing: every time a key is accepted into the expression, allCount++ is compared against maxCombineCount (getMaxCombineCount(), server-configurable). If the same expression references more keys than allowed, the request is rejected. Unlike error 147 (which caps raw condition pairs), this caps how many key references a single @combine expression may contain — it stops combinatorial explosion like "a & b | c & d | ..." with hundreds of terms.

Source

Thrown at APIJSONORM/src/main/java/apijson/orm/AbstractSQLConfig.java:3489

				boolean isBlankOrRightParenthesis = c == ' ' || c == ')';
				if (isOver || isBlankOrRightParenthesis) {
					boolean isEmpty = StringUtil.isEmpty(key, true);
					if (isEmpty && last != ')') {
						throw new IllegalArgumentException(errPrefix + " 中字符 '" + (isOver ? s : s.substring(i))
								+ "' 不合法!" + (c == ' ' ? "空格 ' ' " : "右括号 ')'") + " 左边缺少条件 key !逻辑连接符 & | 左右必须各一个相邻空格!"
								+ "空格不能多也不能少!不允许首尾有空格,也不允许连续空格!左括号 ( 的右边 和 右括号 ) 的左边 都不允许有相邻空格!");
					}

					if (isEmpty == false) {
						if (first == false && lastLogic <= 0) {
							throw new IllegalArgumentException(errPrefix + " 中字符 "
									+ "'" + s.substring(i - key.length() - (isOver ? 1 : 0))
									+ "' 不合法!左边缺少 & | 其中一个逻辑连接符!");
						}

						allCount ++;
						if (allCount > maxCombineCount && maxCombineCount > 0) {
							throw new IllegalArgumentException(errPrefix + " 中字符 '" + s + "' 不合法!"
									+ "其中 key 数量 " + allCount + " 已超过最大值,必须在条件键值对数量 0-" + maxCombineCount + " 内!");
						}

						String column = key;
						int keyIndex = column.indexOf(":");
						column = keyIndex > 0 ? column.substring(0, keyIndex) : column;
						Object value = conditionMap.get(column);
						String wi = "";
						if (value == null && conditionMap.containsKey(column) == false) { // 兼容@null
							isNot = false; // 以占位表达式为准
							size++; // 兼容 key 数量判断
							wi = keyIndex > 0 ? key.substring(keyIndex + 1) : "";
							if (StringUtil.isEmpty(wi)) {
								throw new IllegalArgumentException(errPrefix + " 中字符 '"
										+ key + "' 对应的条件键值对 " + column + ":value 不存在!");
							}
						} else {
							wi = isHaving ? gainHavingItem(quote, table, alias, column, (String) value, containRaw)

View on GitHub (pinned to 5284052872)

Solutions

  1. Reduce terms in @combine; move conditions that are always ANDed out of @combine entirely (keys not in @combine are ANDed by default).
  2. Raise maxCombineCount in server configuration if the use case is legitimate.
  3. Use IN-lists ("id{}": [...]) instead of OR-chains of individual keys.
  4. Count terms client-side before sending (see validation code).

Example fix

// before
{"@combine":"a & b | c & d | e & f | g & h"}
// after (only the ORed part goes in @combine)
{"@combine":"a | c | e | g","b":1,"d":1,"f":1,"h":1}
Defensive patterns

Strategy: validation

Validate before calling

int count = combine.split("[&|]", -1).length; // each split yields a term
if (MAX_COMBINE_COUNT > 0 && count > MAX_COMBINE_COUNT) throw new IllegalStateException("combine too large: " + count);

Type guard

function withinCombineCount(s: string, max: number): boolean { return max <= 0 || s.split(/[&|]/).length <= max; }

Try / catch

catch (IllegalArgumentException e) { /* reduce expression terms, keep default ANDed keys outside @combine */ }

Prevention

When it happens

Trigger: A valid but huge @combine, e.g. dynamically generated "k1 & k2 & ... & k100" while maxCombineCount is 5 (or whatever the deployment configured via maxCombineCount property). Each key occurrence counts, so repeated references also add up.

Common situations: Dynamic filter builders mapping every UI checkbox to a combine term; OR-chains over many optional search fields; strict default limits after a security-hardening upgrade.

Related errors


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