Tencent/APIJSON · error · IllegalArgumentException

{errPrefix} 中字符 '{s}' 不合法!不允许首尾有空格,也不允许连续空格!空格不能多也不能少!逻辑连接符

Error message

{errPrefix} 中字符 '{s}' 不合法!不允许首尾有空格,也不允许连续空格!空格不能多也不能少!逻辑连接符 & | 左右必须各一个相邻空格!左括号 ( 右边和右括号 ) 左边都不允许有相邻空格!

What it means

parseCombineExpression() validates the @combine (or @having combine) logical expression string. The very first check rejects any value that starts or ends with a space. @combine has a strict single-space grammar: '&' and '|' must have exactly one adjacent space on each side, and no other spaces are allowed, so leading/trailing spaces always indicate a malformed expression.

Source

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

	 * @param method
	 * @param quote
	 * @param table
	 * @param alias
	 * @param conditionMap  where 或 having 对应条件的 Map
	 * @param combine
	 * @param verifyName
	 * @param containRaw
	 * @param isHaving
	 * @return
	 * @throws Exception
	 */
	protected String parseCombineExpression(RequestMethod method, String quote, String table, String alias
			, Map<String, Object> conditionMap, String combine, boolean verifyName, boolean containRaw, boolean isHaving) throws Exception {

		String errPrefix = table + (isHaving ? ":{ @having:{ " : ":{ ") + "@combine:'" + combine + (isHaving ? "' } }" : "' }");
		String s = StringUtil.get(combine);
		if (s.startsWith(" ") || s.endsWith(" ") ) {
			throw new IllegalArgumentException(errPrefix + " 中字符 '" + s
					+ "' 不合法!不允许首尾有空格,也不允许连续空格!空格不能多也不能少!"
					+ "逻辑连接符 & | 左右必须各一个相邻空格!左括号 ( 右边和右括号 ) 左边都不允许有相邻空格!");
		}

		if (conditionMap == null) {
			conditionMap = new HashMap<>();
		}
		int size = conditionMap.size();

		int maxCount = isHaving ? getMaxHavingCount() : getMaxWhereCount();
		if (maxCount > 0 && size > maxCount) {
			throw new IllegalArgumentException(table + (isHaving ? ":{ @having:{ " : ":{ ") + "key0:value0, key1:value1... " + combine
					+ (isHaving ? " } }" : " }") + " 中条件 key:value 数量 " + size + " 已超过最大数量,必须在 0-" + maxCount + " 内!");
		}

		String result = "";

		List<Object> preparedValues = getPreparedValueList();

View on GitHub (pinned to 5284052872)

Solutions

  1. Trim the @combine value before sending: combine.strip().
  2. Build expressions programmatically with a helper that joins keys and operators with exactly one space and never pads the ends (see validation code).
  3. Remember the full grammar: single spaces around & and | only; none adjacent to '(' or ')'; no doubled spaces.

Example fix

// before
{"@combine":" id & name "}
// after
{"@combine":"id & name"}
Defensive patterns

Strategy: validation

Validate before calling

if (combine != null && (combine.startsWith(" ") || combine.endsWith(" "))) {
    throw new IllegalArgumentException("@combine must not start/end with a space");
}

Type guard

function isTrimmed(s: string): boolean { return s === s.trim() && !s.includes('  '); }

Prevention

When it happens

Trigger: @combine:"id & name " or " id|name" — note the leading/trailing space. errPrefix shows the table and full combine value. Triggered whenever getWhereString/getHavingString parse a @combine that the caller did not trim.

Common situations: Building @combine by joining strings (" " + part + " "), template literals with stray whitespace, copy-paste from formatted docs. Because the grammar demands exactly one space around operators, developers often over-correct by padding the ends.

Related errors


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