chinabugotech/hutool · error · IllegalArgumentException

Bad expression '{}':{}, we find '[' but no ']' !

Error message

Bad expression '{}':{}, we find '[' but no ']' !

What it means

The same parser rejects a second '[' while a previous '[' is still open (isNumStart already true), i.e. a nested/overlapping bracket that the simple index grammar does not allow. BeanPath supports single-level numeric indices like a[0], not a[0[1]]. This branch is reached when a boundary char is found and isNumStart is already true.

Source

Thrown at hutool-core/src/main/java/cn/hutool/core/bean/BeanPath.java:350

			if ('\'' == c) {
				// 结束
				isInWrap = (false == isInWrap);
				continue;
			}

			if (false == isInWrap && ArrayUtil.contains(EXP_CHARS, c)) {
				// 处理边界符号
				if (CharUtil.BRACKET_END == c) {
					// 中括号(数字下标)结束
					if (false == isNumStart) {
						throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find ']' but no '[' !", expression, i));
					}
					isNumStart = false;
					// 中括号结束加入下标
				} else {
					if (isNumStart) {
						// 非结束中括号情况下发现起始中括号报错(中括号未关闭)
						throw new IllegalArgumentException(StrUtil.format("Bad expression '{}':{}, we find '[' but no ']' !", expression, i));
					} else if (CharUtil.BRACKET_START == c) {
						// 数字下标开始
						isNumStart = true;
					}
					// 每一个边界符之前的表达式是一个完整的KEY,开始处理KEY
				}
				if (builder.length() > 0) {
					localPatternParts.add(builder.toString());
				}
				builder.setLength(0);
			} else {
				// 非边界符号,追加字符
				builder.append(c);
			}
		}

		// 末尾边界符检查
		if (isNumStart) {

View on GitHub (pinned to 8870454b2a)

Solutions

  1. Use chained single-level indices: a[0][1] rather than a[0[1]].
  2. Verify each '[' is immediately followed by digits then ']'.
  3. Generate paths from a structured builder rather than string concatenation.

Example fix

// before
BeanPath p = new BeanPath("matrix[0[1]]");
// after
BeanPath p = new BeanPath("matrix[0][1]");
Defensive patterns

Strategy: validation

Validate before calling

if (path.indexOf('[') != path.lastIndexOf('[') && path.replaceAll("[^\\[]","").length() != path.replaceAll("[^\\]]","").length()) throw new IllegalArgumentException("nested/unbalanced brackets: " + path);

Prevention

When it happens

Trigger: Paths like "a[0[1]]", "a[[0]]", or "a[0][" where a second '[' appears before the first index closes. Also any boundary EXP_CHAR encountered mid-index.

Common situations: Trying to express multi-dimensional arrays with nested brackets (BeanPath uses chained [i][j] instead); malformed generated paths.

Related errors


AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14). Data as JSON: /api/errors/9931320fbf373ef8. Report an issue: GitHub.