Tencent/APIJSON · error · IllegalArgumentException

中字符 ' ' 对应的 :value 不是有效条件键值对!

Error message

{errPrefix} 中字符 '{key}' 对应的 {column}:value 不是有效条件键值对!

What it means

After resolving a @combine key, its SQL fragment wi is produced by gainWhereItem/gainHavingItem. If wi comes back empty (or blank), the key resolved to nothing usable — typically the condition value is an empty string, an empty container, or an operator with no effect — so the expression would contain an empty () group, and the request is rejected instead of emitting invalid SQL.

Solutions

  1. Omit keys with empty values from the request object entirely instead of sending "key":"".
  2. Filter empty-string/empty-collection values out of the condition map before sending (see validation code).
  3. If using placeholder keys ('col:suffix' form), ensure the suffix produces a real condition.

Example fix

// before
{"User":{"id":1,"remark":"","@combine":"id & remark"}}
// after
{"User":{"id":1,"@combine":"id"}}
Defensive patterns

Strategy: validation

Validate before calling

boolean effective = tableObj.entrySet().stream()
    .filter(e -> !e.getKey().startsWith("@"))
    .allMatch(e -> e.getValue() != null && !"".equals(String.valueOf(e.getValue()).strip())
        && !(e.getValue() instanceof Collection && ((Collection<?>) e.getValue()).isEmpty()));
if (!effective) throw new IllegalStateException("empty condition value present");

Type guard

function isEffectiveValue(v: unknown): boolean {
  if (v === null || v === undefined) return false;
  if (typeof v === 'string') return v.trim().length > 0;
  if (Array.isArray(v)) return v.length > 0;
  return true;
}

Prevention

When it happens

Trigger: @combine:"remark & id" where the request has "remark":"" (empty value) — the key exists (so 151 doesn't fire) but gainWhereItem returns an empty string. Similarly "tag{}":[] (empty array) or an @having entry whose value produces no SQL. StringUtil.isEmpty(wi, true) with trim=true is the test at line 3518.

Common situations: Optional filter fields sent as empty strings from HTML forms; dynamically added filters whose value is '' or []; JSON built with null/empty defaults that still create map entries.

Related errors


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

Appendix: source

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

							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)
									: gainWhereItem(column, value, method, verifyName);
						}

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

						if (StringUtil.isEmpty(wi, true)) {  // 转成 1=1 ?
							throw new IllegalArgumentException(errPrefix + " 中字符 '" + key
									+ "' 对应的 " + column + ":value 不是有效条件键值对!");
						}

						Integer count = usedKeyCountMap.get(column);
						count = count == null ? 1 : count + 1;
						if (count > maxCombineKeyCount && maxCombineKeyCount > 0) {
							throw new IllegalArgumentException(errPrefix + " 中字符 '" + s + "' 不合法!"
									+ "其中 '" + column + "' 重复引用,次数 " + count
									+ " 已超过最大值,必须在 0-" + maxCombineKeyCount + " 内!");
						}
						usedKeyCountMap.put(column, count);

						result += "( " + gainCondition(isNot, wi) + " )";
						isNot = false;
						first = false;
					}

					key = "";

View on GitHub (pinned to 5284052872)