{"record":{"id":"9157ccdc7917696f","repo":"mybatis/mybatis-3","slug":"parameter-key-not-found-available-param","errorCode":null,"errorMessage":"Parameter '\" + key + \"' not found. Available parameters are \" + this.keySet()","messagePattern":"Parameter '\" \\+ key \\+ \"' not found\\. Available parameters are \" \\+ this\\.keySet\\(\\)","errorType":"exception","errorClass":"BindingException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/session/defaults/DefaultSqlSession.java","lineNumber":329,"sourceCode":"    return !autoCommit && dirty || force;\n  }\n\n  private Object wrapCollection(final Object object) {\n    return ParamNameResolver.wrapToMapIfCollection(object, null);\n  }\n\n  /**\n   * @deprecated Since 3.5.5\n   */\n  @Deprecated\n  public static class StrictMap<V> extends HashMap<String, V> {\n\n    private static final long serialVersionUID = -5741767162221585340L;\n\n    @Override\n    public V get(Object key) {\n      if (!super.containsKey(key)) {\n        throw new BindingException(\"Parameter '\" + key + \"' not found. Available parameters are \" + this.keySet());\n      }\n      return super.get(key);\n    }\n\n  }\n\n}\n","sourceCodeStart":311,"sourceCodeEnd":337,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/session/defaults/DefaultSqlSession.java#L311-L337","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nMap<String,Object> p = new HashMap<>(); p.put(\"id\", 7);\n<!-- XML: WHERE id = #{userId} -->\n// after\nMap<String,Object> p = new HashMap<>(); p.put(\"userId\", 7);\n<!-- XML: WHERE id = #{userId} -->","handlingStrategy":"validation","validationCode":"if (paramMap.containsKey(\"userId\")) {\n  sqlSession.selectOne(\"findUser\", paramMap);\n} else {\n  throw new IllegalArgumentException(\"missing key userId; have \" + paramMap.keySet());\n}","typeGuard":null,"tryCatchPattern":"try { session.selectOne(\"findUser\", paramMap); }\ncatch (BindingException e) { /* message lists available keys; fix placeholder or add key */ throw e; }","preventionTips":["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."],"tags":["mybatis","parameters","binding-exception","map-params"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}