{"record":{"id":"c1a316e15b937adc","repo":"apache/cassandra","slug":"invalid-annotations-you-have-more-than-one-repla","errorCode":null,"errorMessage":"Invalid annotations, you have more than one @Replaces annotation in Config class with same old name(<oldName>) defined.","messagePattern":"Invalid annotations, you have more than one @Replaces annotation in Config class with same old name\\(<oldName>\\) defined\\.","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/config/Replacements.java","lineNumber":52,"sourceCode":"    {\n    }\n\n    /**\n     * @param klass to get replacements for\n     * @return map of old names and replacements needed.\n     */\n    public static Map<Class<? extends Object>, Map<String, Replacement>> getNameReplacements(Class<? extends Object> klass)\n    {\n        List<Replacement> replacements = getReplacementsRecursive(klass);\n        Map<Class<?>, Map<String, Replacement>> objectOldNames = new HashMap<>();\n        for (Replacement r : replacements)\n        {\n            Map<String, Replacement> oldNames = objectOldNames.computeIfAbsent(r.parent, ignore -> new HashMap<>());\n            if (!oldNames.containsKey(r.oldName))\n                oldNames.put(r.oldName, r);\n            else\n            {\n                throw new ConfigurationException(\"Invalid annotations, you have more than one @Replaces annotation in \" +\n                                                 \"Config class with same old name(\" + r.oldName + \") defined.\");\n            }\n        }\n        return objectOldNames;\n    }\n\n    /**\n     * @param klass to get replacements for\n     * @return map of old names and replacements needed.\n     */\n    private static List<Replacement> getReplacementsRecursive(Class<?> klass)\n    {\n        Set<Class<?>> seen = new HashSet<>(); // to make sure not to process the same type twice\n        List<Replacement> accum = new ArrayList<>();\n        getReplacementsRecursive(seen, accum, klass);\n        return accum.isEmpty() ? Collections.emptyList() : accum;\n    }\n","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/config/Replacements.java#L34-L70","documentation":"Replacements.getNameReplacements() builds the map of deprecated->new config names from @Replaces annotations on Config fields. If two fields' @Replaces annotations declare the same oldName, the mapping would be ambiguous, so it throws ConfigurationException. This is a developer-facing error when authoring Config definitions, not an operator config problem.","triggerScenarios":"Adding a field to Config with @Replaces(oldName = \"x\") when another field already replaces oldName \"x\".","commonSituations":"Merging upstream patches that both introduce a replacement for the same deprecated setting; copy-pasting a @Replaces annotation without changing oldName; refactoring a renamed setting twice.","solutions":["Remove or change the duplicate @Replaces(oldName=...) so each old name maps to exactly one field","Search Config.java for the offending old name to find the conflicting annotations","If intentional, consolidate the migration logic into a single field's @Replaces"],"exampleFix":"// before\n@Replaces(\"old_setting\") public volatile int newSettingA;\n@Replaces(\"old_setting\") public volatile int newSettingB;\n// after\n@Replaces(\"old_setting\") public volatile int newSettingA; // only one replaces each old name","handlingStrategy":"validation","validationCode":"Set<String> seen = new HashSet<>();\nfor (Field f : Config.class.getDeclaredFields()) {\n    Replaces r = f.getAnnotation(Replaces.class);\n    if (r != null && !seen.add(r.oldName()))\n        throw new IllegalStateException(\"Duplicate @Replaces oldName: \" + r.oldName());\n}","typeGuard":null,"tryCatchPattern":"try { Map<String, Replacement> m = Replacements.getNameReplacements(...); }\ncatch (ConfigurationException e) { throw new IllegalStateException(\"Fix duplicate @Replaces annotations: \" + e.getMessage()); }","preventionTips":["Grep Config.java for @Replaces(oldName = \"x\") before adding a new replacement for x","Keep a single owner field per deprecated setting name","Review merge conflicts touching @Replaces annotations carefully"],"tags":["annotations","configuration","developer-error"],"backgroundTag":"conflicting-config-options","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}