Tencent/APIJSON · error · IllegalArgumentException

子查询 / : 中 value 只能为 [ALL, ANY] 中的一个!

Error message

子查询 {}/{}:{ range:value } 中 value 只能为 [ALL, ANY] 中的一个!

What it means

When parsing a 'key{}@' subquery object, AbstractObjectParser reads its 'range' field and only allows the constants SUBQUERY_RANGE_ALL ('ALL') or SUBQUERY_RANGE_ANY ('ANY') — these map to SQL ALL/ANY quantifiers. If range is present and is neither of those exact strings (case-sensitive), an IllegalArgumentException is thrown naming the path and key.

Solutions

  1. Use exactly "ALL" or "ANY" (uppercase) for the range value.
  2. Omit the range key entirely when you don't need the ALL/ANY quantifier.
  3. For 'IN'-style membership, drop range and rely on the default subquery behavior instead of trying range values.

Example fix

// before
"id{}@": { "from": "Comment", "range": "all", "Comment": { "@column": "userId" } }
// after
"id{}@": { "from": "Comment", "range": "ALL", "Comment": { "@column": "userId" } }
Defensive patterns

Strategy: validation

Validate before calling

Object range = subquery.get("range");
if (range != null && !"ALL".equals(range) && !"ANY".equals(range)) {
  throw new IllegalArgumentException("range must be ALL or ANY (uppercase)");
}

Type guard

function isValidRange(r: unknown): boolean {
  return r == null || r === 'ALL' || r === 'ANY';
}

Prevention

When it happens

Trigger: A request like "id{}@": { "from": "Comment", "Comment": { "@column": "userId" }, "range": "all" } — lowercase 'all', 'SOME', 'IN', or any other string. Omitting range entirely is fine (null passes).

Common situations: Writing 'all'/'any' in lowercase; assuming SQL 'SOME' or 'IN' semantics are supported; copy-pasting from docs that capitalize differently.

Related errors


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

Appendix: source

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

    //private boolean hasOtherKeyNotFun = false;

    /**解析普通成员
	 * @param key
	 * @param value
	 * @return whether parse succeed
	 */
	@Override
	public boolean onParse(@NotNull String key, @NotNull Object value) throws Exception {
		if (key.endsWith("@")) {  // StringUtil.isPath((String) value)) {
			// [] 内主表 position > 0 时,用来生成 SQLConfig<T, M, L> 的键值对全都忽略,不解析
			if (value instanceof Map<?, ?>) {  // key{}@ getRealKey, SQL 子查询对象,JSONRequest -> SQLConfig.getSQL
				String replaceKey = key.substring(0, key.length() - 1);

				M subquery = (M) value;
				String range = getString(subquery, KEY_SUBQUERY_RANGE);
				if (range != null && SUBQUERY_RANGE_ALL.equals(range) == false && SUBQUERY_RANGE_ANY.equals(range) == false) {
					throw new IllegalArgumentException("子查询 " + path + "/" + key + ":{ range:value } 中 value 只能为 ["
                            + SUBQUERY_RANGE_ALL + ", " + SUBQUERY_RANGE_ANY + "] 中的一个!");
				}

				L arr = parser.onArrayParse(subquery, path, key, true, null);

				M obj = arr == null || arr.isEmpty() ? null : JSON.get(arr, 0);
				if (obj == null) {
					throw new Exception("服务器内部错误,解析子查询 " + path + "/" + key + ":{ } 为 Subquery 对象失败!");
				}

				String from = getString(subquery, apijson.JSONRequest.KEY_SUBQUERY_FROM);
				boolean isEmpty = StringUtil.isEmpty(from);
				M arrObj = isEmpty ? null : JSON.get(obj, from);
				if (isEmpty) {
					Set<Entry<String, Object>> set = obj.entrySet();
					for (Entry<String, Object> e : set) {
						String k = e == null ? null : e.getKey();
						Object v = k == null ? null : e.getValue();

View on GitHub (pinned to 5284052872)