mybatis/mybatis-3 · error · IllegalArgumentException

key + " is ambiguous in " + name + " (try using the full nam

Error message

key + " is ambiguous in " + name + " (try using the full name including the namespace, or rename one of the entries)

What it means

StrictMap stores a short-name index (the segment after the last dot) next to every full key. When two different full keys share the same short name, the short slot is overwritten with the sentinel AMBIGUITY_INSTANCE; a later get() by that short name throws IllegalArgumentException saying the key is ambiguous and suggesting the full name including namespace. This only affects lookups that omit the namespace.

Source

Thrown at src/main/java/org/apache/ibatis/session/Configuration.java:1188

    }

    @Override
    public boolean containsKey(Object key) {
      if (key == null) {
        return false;
      }

      return super.get(key) != null;
    }

    @Override
    public V get(Object key) {
      V value = super.get(key);
      if (value == null) {
        throw new IllegalArgumentException(name + " does not contain value for " + key);
      }
      if (AMBIGUITY_INSTANCE == value) {
        throw new IllegalArgumentException(key + " is ambiguous in " + name
            + " (try using the full name including the namespace, or rename one of the entries)");
      }
      return value;
    }

    private String getShortName(String key) {
      final String[] keyParts = key.split("\\.");
      return keyParts[keyParts.length - 1];
    }
  }

}

View on GitHub (pinned to 008069adb1)

Solutions

  1. Always reference statements and maps by their fully-qualified name: namespace + '.' + id.
  2. If you truly need short names, rename one of the colliding ids so short names are unique.
  3. Audit dynamically-built statement strings to ensure the namespace prefix is retained.

Example fix

// before
sqlSession.selectList("findById", 1);
// after
sqlSession.selectList("com.acme.UserMapper.findById", 1);
Defensive patterns

Strategy: validation

Validate before calling

String full = UserMapper.class.getName() + ".findById";
// never look up by short name; assert the full name resolves
assert factory.getConfiguration().hasStatement(full);

Try / catch

try { session.selectList("findById"); }
catch (IllegalArgumentException e) { /* 'is ambiguous' -> switch to full name including namespace */ throw e; }

Prevention

When it happens

Trigger: Two statements named findById in different namespaces (e.g. UserMapper.findById and OrderMapper.findById) and a lookup with just "findById"; two resultMaps with the same short id across namespaces referenced without namespace; statement string built dynamically and accidentally stripped of the namespace part.

Common situations: Generic DAO code calling statements by short id; copy-paste ids across mappers (findById everywhere); older code that relied on short names before mappers grew; string manipulation (split on '.') that drops the namespace.

Related errors


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