chinabugotech/hutool · error · IllegalArgumentException
Bad expression '{}':{}, we find ']' but no '[' !
Error message
Bad expression '{}':{}, we find ']' but no '[' ! What it means
BeanPath parses dotted/bracket property paths (e.g. a.b[0].c). When it encounters a closing ']' without a preceding '[' having opened an index, it rejects the expression as malformed. The throw point is the BRACKET_END branch when isNumStart is false, meaning the parser was not currently inside an index.
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/bean/BeanPath.java:343
c = expression.charAt(i);
if (0 == i && '$' == c) {
// 忽略开头的$符,表示当前对象
isStartWith = true;
continue;
}
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 {View on GitHub (pinned to 8870454b2a)
Solutions
- Balance brackets: every '[' must precede a matching ']' and contain a numeric index.
- Validate the path with a regex or a test BeanPath construction before runtime use.
- Strip stray brackets from generated/computed path strings.
Example fix
// before
BeanPath p = new BeanPath("items].name");
// after
BeanPath p = new BeanPath("items[0].name"); Defensive patterns
Strategy: validation
Validate before calling
if (!path.matches("^[^.\\[\\]]+(\\.[^.\\[\\]]+)*(\\[\\d+\\])*$")) throw new IllegalArgumentException("bad BeanPath: " + path); Type guard
static boolean validBeanPath(String p) { return p != null && p.chars().filter(c->c=='[').count() == p.chars().filter(c->c==']').count() && !p.contains("]"); } Prevention
- Validate property paths from untrusted sources before constructing BeanPath.
- Generate paths from a structured builder, not string concatenation.
When it happens
Trigger: Constructing BeanPath with a string like "a].b", "[0]]", or "a[]" style stray brackets. Any path where ']' appears before a matching '['.
Common situations: User-supplied property paths from config/UI that weren't validated; concatenating path fragments incorrectly (e.g. appending "]" unconditionally); JSON-pointer vs BeanPath syntax confusion.
Related errors
- Bad expression '{}':{}, we find '[' but no ']' !
- Error Machine number!
- Invalid Getter or Setter name:
- Record class [] has no components
- Illegal hexadecimal character {} at index {}
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/6f6fc7bf07c7eb56.
Report an issue: GitHub.