mybatis/mybatis-3 · error · BuilderException
An invalid property '{name}' was found in mapping #{{content
Error message
An invalid property '{name}' was found in mapping #{{content}}. Valid properties are {PARAMETER_PROPERTIES} What it means
Thrown when a #{} placeholder option list contains a property name outside the allowed set. The valid set (PARAMETER_PROPERTIES) is javaType, jdbcType, mode, numericScale, resultMap, typeHandler, jdbcTypeName (per ParameterMapping). Unrecognized names (e.g. 'type', 'value', 'nullable') are rejected with this message listing the valid names.
Source
Thrown at src/main/java/org/apache/ibatis/builder/ParameterMappingTokenHandler.java:121
builder.typeHandler(typeHandler);
ParameterMode mode = null;
for (Map.Entry<String, String> entry : propertiesMap.entrySet()) {
String name = entry.getKey();
String value = entry.getValue();
if ("mode".equals(name)) {
mode = resolveParameterMode(value);
builder.mode(mode);
} else if ("numericScale".equals(name)) {
builder.numericScale(Integer.valueOf(value));
} else if ("resultMap".equals(name)) {
builder.resultMapId(value);
} else if ("jdbcTypeName".equals(name)) {
builder.jdbcTypeName(value);
} else if ("expression".equals(name)) {
throw new BuilderException("Expression based parameters are not supported yet");
} else {
throw new BuilderException("An invalid property '" + name + "' was found in mapping #{" + content
+ "}. Valid properties are " + PARAMETER_PROPERTIES);
}
}
if (!ParameterMode.OUT.equals(mode) && paramExists) {
if (metaParameters.hasGetter(propertyTokenizer.getName())) {
builder.value(metaParameters.getValue(property));
} else if (parameterObject == null) {
builder.value(null);
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
builder.value(parameterObject);
} else {
MetaObject metaObject = configuration.newMetaObject(parameterObject);
builder.value(metaObject.getValue(property));
}
}
return builder.build();
}
View on GitHub (pinned to 008069adb1)
Solutions
- Use one of the valid option names: javaType, jdbcType, mode, numericScale, resultType? (resultMap for OUT params), typeHandler
- Check the exact spelling in the error message's PARAMETER_PROPERTIES list it prints
- Remove options that are not needed — plain #{property} is usually correct
Example fix
<!-- before -->
#{id,type=INTEGER}
<!-- after -->
#{id,jdbcType=INTEGER} Defensive patterns
Strategy: validation
Validate before calling
private static final Set<String> VALID = Set.of("javaType","jdbcType","mode","numericScale","resultMap","typeHandler");
void checkPlaceholderOptions(String content) {
Map<String,String> opts = new ParameterExpression(content);
for (String k : opts.keySet()) {
if (!VALID.contains(k)) throw new IllegalArgumentException("Invalid #{} option '" + k + "' in " + content);
}
} Try / catch
try {
new ParameterExpression(content);
} catch (BuilderException e) {
if (e.getMessage().contains("Valid properties are")) {
// surface allowed list to the developer
throw new IllegalArgumentException("Bad placeholder options: " + content, e);
}
throw e;
} Prevention
- Learn the valid option list once: javaType, jdbcType, mode, numericScale, resultMap, typeHandler
- Let the IDE's MyBatis plugin validate mapper syntax before runtime
When it happens
Trigger: Writing #{id,type=INTEGER} instead of #{id,jdbcType=INTEGER}, or #{id,nullable=true} — any option key not in ParameterMapping's PARAMETER_PROPERTIES constant.
Common situations: Guessing option names ('type' instead of 'jdbcType'), copy-paste from JPA/NamedParameterJdbcTemplate style syntax, or typos like 'jdbcTyp'.
Related errors
- Parsing error in {{expression}} in position {p}
- Dots are not allowed in element names, please remove it from
- cache-ref element requires a namespace attribute.
- Expression based parameters are not supported yet
- Parsing error was found in mapping #{{content}}. Check synt
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/68bf90f357634354.
Report an issue: GitHub.