{"record":{"id":"d77f99ec33aecd05","repo":"mybatis/mybatis-3","slug":"key-is-ambiguous-in-name-try-using-th","errorCode":null,"errorMessage":"key + \" is ambiguous in \" + name + \" (try using the full name including the namespace, or rename one of the entries)","messagePattern":"key \\+ \" is ambiguous in \" \\+ name \\+ \" \\(try using the full name including the namespace, or rename one of the entries\\)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/session/Configuration.java","lineNumber":1188,"sourceCode":"    }\n\n    @Override\n    public boolean containsKey(Object key) {\n      if (key == null) {\n        return false;\n      }\n\n      return super.get(key) != null;\n    }\n\n    @Override\n    public V get(Object key) {\n      V value = super.get(key);\n      if (value == null) {\n        throw new IllegalArgumentException(name + \" does not contain value for \" + key);\n      }\n      if (AMBIGUITY_INSTANCE == value) {\n        throw new IllegalArgumentException(key + \" is ambiguous in \" + name\n            + \" (try using the full name including the namespace, or rename one of the entries)\");\n      }\n      return value;\n    }\n\n    private String getShortName(String key) {\n      final String[] keyParts = key.split(\"\\\\.\");\n      return keyParts[keyParts.length - 1];\n    }\n  }\n\n}\n","sourceCodeStart":1170,"sourceCodeEnd":1201,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/session/Configuration.java#L1170-L1201","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Always reference statements and maps by their fully-qualified name: namespace + '.' + id.","If you truly need short names, rename one of the colliding ids so short names are unique.","Audit dynamically-built statement strings to ensure the namespace prefix is retained."],"exampleFix":"// before\nsqlSession.selectList(\"findById\", 1);\n// after\nsqlSession.selectList(\"com.acme.UserMapper.findById\", 1);","handlingStrategy":"validation","validationCode":"String full = UserMapper.class.getName() + \".findById\";\n// never look up by short name; assert the full name resolves\nassert factory.getConfiguration().hasStatement(full);","typeGuard":null,"tryCatchPattern":"try { session.selectList(\"findById\"); }\ncatch (IllegalArgumentException e) { /* 'is ambiguous' -> switch to full name including namespace */ throw e; }","preventionTips":["Always use namespace-qualified statement names.","Ban short-name lookups in code review.","Give ids descriptive names so cross-mapper collisions are obvious (findUserById vs findById)."],"tags":["mybatis","configuration","ambiguous-key","namespace"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}