mybatis/mybatis-3 · error · BindingException
Parameter '" + key + "' not found. Available parameters are
Error message
Parameter '" + key + "' not found. Available parameters are " + this.keySet()
What it means
DefaultSqlSession.StrictMap (an internal map used when MyBatis wraps parameters, notably for Map-based parameter lookup in selectMap key extraction and map parameter access) throws BindingException 'Parameter '...' not found. Available parameters are ...' when a #{...} placeholder or mapKey references a key that is absent from the parameter map. The message helpfully lists the actual key set, so the mismatch is usually visible immediately.
Source
Thrown at src/main/java/org/apache/ibatis/session/defaults/DefaultSqlSession.java:329
return !autoCommit && dirty || force;
}
private Object wrapCollection(final Object object) {
return ParamNameResolver.wrapToMapIfCollection(object, null);
}
/**
* @deprecated Since 3.5.5
*/
@Deprecated
public static class StrictMap<V> extends HashMap<String, V> {
private static final long serialVersionUID = -5741767162221585340L;
@Override
public V get(Object key) {
if (!super.containsKey(key)) {
throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet());
}
return super.get(key);
}
}
}
View on GitHub (pinned to 008069adb1)
Solutions
- Compare the key named in the message against the 'Available parameters are [...]' list and align the XML placeholder with an existing key (or put the missing key into the map).
- Use @Param on multi-argument mapper methods and reference exactly those names in XML.
- Centralize parameter key names as shared constants used by both Java and (via properties/[$]{} if needed) XML.
Example fix
// before
Map<String,Object> p = new HashMap<>(); p.put("id", 7);
<!-- XML: WHERE id = #{userId} -->
// after
Map<String,Object> p = new HashMap<>(); p.put("userId", 7);
<!-- XML: WHERE id = #{userId} --> Defensive patterns
Strategy: validation
Validate before calling
if (paramMap.containsKey("userId")) {
sqlSession.selectOne("findUser", paramMap);
} else {
throw new IllegalArgumentException("missing key userId; have " + paramMap.keySet());
} Try / catch
try { session.selectOne("findUser", paramMap); }
catch (BindingException e) { /* message lists available keys; fix placeholder or add key */ throw e; } Prevention
- Define map keys as constants shared by Java and referenced consistently in XML.
- Prefer typed parameter objects or @Param over raw Map parameters.
- The exception message prints the available key set — use it to fix the mismatch immediately.
When it happens
Trigger: A mapper method taking Map<String,Object> params with XML using #{userId} while the map was filled with key 'id'; selectMap(statement, mapKey) where mapKey names a property the result objects do not have; @Param names disagreeing with XML placeholders when the multi-param map wrapping kicks in.
Common situations: Service code putting keys with one naming convention while the XML uses another; copy-pasted XML blocks referencing old parameter names; refactoring @Param names without touching XML; constants used for map keys drifting from XML strings.
Related errors
- Parameter '{key}' not found. Available parameters are {keySe
- {methodName} cannot have multiple {paramType} parameters
- The JDBC Type must be specified for output parameter. Param
- There is no getter for property named '{}' in '{}'
- Could not find type handler for Java type '" + propertyGener
AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14).
Data as JSON: /api/errors/9157ccdc7917696f.
Report an issue: GitHub.