{"record":{"id":"3ad40cefe286024e","repo":"mybatis/mybatis-3","slug":"invalid-index-syntax-in-property-missing-cl","errorCode":null,"errorMessage":"Invalid index syntax in property: '{}'. Missing closing bracket.","messagePattern":"Invalid index syntax in property: '(.+?)'\\. Missing closing bracket\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/reflection/property/PropertyTokenizer.java","lineNumber":42,"sourceCode":"  private String name;\n  private final String indexedName;\n  private String index;\n  private final String children;\n\n  public PropertyTokenizer(String fullname) {\n    int delim = fullname.indexOf('.');\n    if (delim > -1) {\n      name = fullname.substring(0, delim);\n      children = fullname.substring(delim + 1);\n    } else {\n      name = fullname;\n      children = null;\n    }\n    indexedName = name;\n    delim = name.indexOf('[');\n    if (delim > -1) {\n      if (children == null && !name.endsWith(\"]\")) {\n        throw new IllegalArgumentException(\n            \"Invalid index syntax in property: '\" + name + \"'. Missing closing bracket.\");\n      }\n      index = name.substring(delim + 1, name.length() - 1);\n      name = name.substring(0, delim);\n    }\n  }\n\n  public String getName() {\n    return name;\n  }\n\n  public String getIndex() {\n    return index;\n  }\n\n  public String getIndexedName() {\n    return indexedName;\n  }","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/reflection/property/PropertyTokenizer.java#L24-L60","documentation":"PropertyTokenizer parses indexed property paths like 'list[0].name' or 'map[key]'. When a property name (with no remaining children after the last '.') contains '[' but the overall name does not end with ']', the index cannot be extracted, so an IllegalArgumentException is thrown. This is a malformed property-expression error, typically caused by a typo in a mapper XML parameter expression or in MetaObject.getValue/setValue path.","triggerScenarios":"MetaObject.getValue(\"items[0\") or setValue on a path with an unclosed bracket; #{item[0.name} in a mapper (OGNL/parameter path with missing ']'); dynamic SQL concatenation that drops the closing bracket from an index expression like '${list[' + i + '.id]' built incorrectly.","commonSituations":"Hand-built property expressions in dynamic SQL (<foreach> with index interpolation); typos in resultMap/parameter expressions; string-concatenated index expressions where the ']' lands after a '.' separator instead of before it (e.g. 'a[0.b]' leaves children non-null and index parsing malformed).","solutions":["Fix the property expression so every '[' is closed with ']' before any '.' child separator: 'items[0].name'","When concatenating indices in dynamic SQL, place the ']' immediately after the index: \"items[\" + i + \"].name\"","Validate/escape user-supplied property paths before passing them to MetaObject","Log the exact expression string at the call site to spot the malformed segment"],"exampleFix":"<!-- before -->\nSELECT * FROM t WHERE id = #{items[0}\n\n<!-- after -->\nSELECT * FROM t WHERE id = #{items[0].id}","handlingStrategy":"validation","validationCode":"boolean validIndexedProperty(String path) {\n  for (String seg : path.split(\"\\\\.\")) {\n    int open = seg.indexOf('[');\n    if (open > -1 && !seg.endsWith(\"]\")) {\n      return false;\n    }\n  }\n  return true;\n}\n// call before MetaObject.getValue(path)/setValue(path, v)","typeGuard":null,"tryCatchPattern":"try {\n  metaObject.getValue(path);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Missing closing bracket\")) {\n    // reject/repair the property expression; surface to caller as config error\n  } else { throw e; }\n}","preventionTips":["Build indexed expressions with a single format template, never string concatenation across the bracket","Unit-test property-path builders for bracket balance","Prefer simple dotted paths and let <foreach> handle iteration"],"tags":["reflection","property-parsing","dynamic-sql","mybatis"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}