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

  1. 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).
  2. Use @Param on multi-argument mapper methods and reference exactly those names in XML.
  3. 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

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


AI-assisted analysis of mybatis/mybatis-3@008069adb1 (2026-08-14). Data as JSON: /api/errors/9157ccdc7917696f. Report an issue: GitHub.