{"record":{"id":"4822ff39e05d1aab","repo":"alibaba/ARouter","slug":"string-format-tiptext-key","errorCode":null,"errorMessage":"String.format(tipText, key)","messagePattern":"String\\.format\\(tipText, key\\)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"arouter-api/src/main/java/com/alibaba/android/arouter/base/UniqueKeyTreeMap.java","lineNumber":24,"sourceCode":" * TreeMap with unique key.\n *\n * @author zhilong <a href=\"mailto:zhilong.lzl@alibaba-inc.com\">Contact me.</a>\n * @version 1.0\n * @since 2017/2/22 下午5:01\n */\npublic class UniqueKeyTreeMap<K, V> extends TreeMap<K, V> {\n    private String tipText;\n\n    public UniqueKeyTreeMap(String exceptionText) {\n        super();\n\n        tipText = exceptionText;\n    }\n\n    @Override\n    public V put(K key, V value) {\n        if (containsKey(key)) {\n            throw new RuntimeException(String.format(tipText, key));\n        } else {\n            return super.put(key, value);\n        }\n    }\n}\n","sourceCodeStart":6,"sourceCodeEnd":30,"githubUrl":"https://github.com/alibaba/ARouter/blob/84f451d244e3fb1d0e37801de1b9ee2af2f81d68/arouter-api/src/main/java/com/alibaba/android/arouter/base/UniqueKeyTreeMap.java#L6-L30","documentation":"UniqueKeyTreeMap is an internal ARouter map that guarantees unique keys for route/interceptor/provider indexing. put() throws a RuntimeException when the key already exists, formatting the map's tipText (an exception template like 'Path already registered, please check the repeated route!') with the duplicate key.","triggerScenarios":"Registering two RouteMeta entries with the same path/class during Warehouse loading — e.g. two @Route(path=\"/x/y\") annotations with the same path, duplicated route classes generated by the compiler plugin, or LogisticsCenter.init being run twice over the same class set.","commonSituations":"Two modules declare the same route path; a stale generated class from an old build is still on the classpath after refactoring a path; multi-module projects where different teams collide on a path prefix.","solutions":["Search the codebase for a duplicate @Route(path=...) value and rename one path uniquely","Run gradle clean to purge stale generated ARouter group classes from old builds","If two modules must share a path, unify it in one module and depend on it from the other"],"exampleFix":"// before\n@Route(path = \"/user/detail\")\npublic class UserDetailActivity {...}\n// (another module)\n@Route(path = \"/user/detail\")\npublic class UserDetail2Activity {...}\n// after\n@Route(path = \"/user/detail\")\npublic class UserDetailActivity {...}\n// (another module)\n@Route(path = \"/user/detail2\")\npublic class UserDetail2Activity {...}","handlingStrategy":"validation","validationCode":"Set<String> seen = new HashSet<>();\nfor (RouteMeta m : allRouteMetas()) {\n    if (!seen.add(m.getPath())) {\n        throw new IllegalStateException(\"Duplicate route path registered: \" + m.getPath());\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    arouter.init(application);\n} catch (HandlerException e) {\n    if (e.getCause() instanceof RuntimeException && e.getMessage().contains(\"already registered\")) {\n        Log.e(TAG, \"Duplicate route path detected, see cause\", e);\n    }\n}","preventionTips":["Keep one owner per route path; centralize shared paths in a single module","Run gradle clean after renaming/moving routes to purge stale generated classes","Add a CI check that scans @Route annotations for duplicate paths"],"tags":["arouter","duplicate-key","route-registration"],"backgroundTag":"duplicate-key-registration","analyzedSha":"84f451d244e3fb1d0e37801de1b9ee2af2f81d68","analyzedAt":"2026-09-06T13:30:41.084Z","contentChangedAt":"2026-09-06T13:30:41.084Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}