{"record":{"id":"11dcf3b969d5beec","repo":"SonarSource/sonarqube","slug":"a-removed-rule-with-the-key-s-already-exists","errorCode":null,"errorMessage":"A removed rule with the key '%s' already exists","messagePattern":"A removed rule with the key '(.+?)' already exists","errorType":"exception","errorClass":"ReactivationException","httpStatus":400,"severity":"error","filePath":"server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/RuleCreator.java","lineNumber":273,"sourceCode":"          .setType(type)\n          .setSeverity(severity);\n      }\n    }\n  }\n\n  private void createCustomRuleParams(@Nullable String paramValue, RuleDto ruleDto, RuleParamDto templateRuleParam, DbSession dbSession) {\n    RuleParamDto ruleParamDto = RuleParamDto.createFor(ruleDto)\n      .setName(templateRuleParam.getName())\n      .setType(templateRuleParam.getType())\n      .setDescription(templateRuleParam.getDescription())\n      .setDefaultValue(paramValue);\n    dbClient.ruleDao().insertRuleParam(dbSession, ruleDto, ruleParamDto);\n  }\n\n  private RuleDto updateExistingRule(RuleDto ruleDto, NewCustomRule newRule, RuleDto templateRule, DbSession dbSession) {\n    if (ruleDto.getStatus().equals(RuleStatus.REMOVED)) {\n      if (newRule.isPreventReactivation()) {\n        throw new ReactivationException(format(\"A removed rule with the key '%s' already exists\", ruleDto.getKey().rule()), ruleDto.getKey());\n      } else {\n        ruleDto.setStatus(RuleStatus.READY)\n          .setName(newRule.name())\n          .replaceRuleDescriptionSectionDtos(Set.of(\n            createDefaultRuleDescriptionSection(uuidFactory.create(), newRule.markdownDescription())))\n          .setUpdatedAt(system2.now());\n\n        ruleDto.replaceAllDefaultImpacts(Set.of());\n        setCleanCodeAttributeAndImpacts(newRule, ruleDto, templateRule);\n\n        dbClient.ruleDao().update(dbSession, ruleDto);\n        for (RuleParamDto ruleParamDto : dbClient.ruleDao().selectRuleParamsByRuleKey(dbSession, ruleDto.getKey())) {\n          String newValue = Strings.emptyToNull(newRule.parameter(ruleParamDto.getName()));\n          ruleParamDto.setDefaultValue(newValue);\n          dbClient.ruleDao().updateRuleParam(dbSession, ruleDto, ruleParamDto);\n        }\n      }\n    } else {","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/RuleCreator.java#L255-L291","documentation":"When creating a custom rule, SonarQube may find an existing rule with the same key whose status is REMOVED. RuleCreator.updateExistingRule throws this ReactivationException if the request sets preventReactivation=true, refusing to silently resurrect a removed rule; the exception carries the removed rule's key for auditing.","triggerScenarios":"Creating (or reactivating) a custom rule via api/rules/create with preventReactivation=true while a rule with the same key exists in REMOVED status.","commonSituations":"Re-adding a rule that was deleted earlier after a rule-set update; bulk rule imports re-running over previously removed keys; quality-profile reactivations with the safety flag enabled.","solutions":["Set preventReactivation=false to allow the removed rule to be restored to READY (the code path then reactivates it).","Choose a different rule key if the removed rule should stay removed.","If intentional, permanently clean the REMOVED rule record before recreating the key."],"exampleFix":"// before\nPOST /api/rules/create?custom_key=old-rule&prevent_reactivation=true  (removed rule 'old-rule' exists)\n\n// after\nPOST /api/rules/create?custom_key=old-rule&prevent_reactivation=false","handlingStrategy":"try-catch","validationCode":"// check for existing removed rule before create\nRuleDto existing = dbClient.ruleDao().selectByKey(dbSession, RuleKey.of(repo, key));\nboolean removedExists = existing != null && RuleStatus.REMOVED.equals(existing.getStatus());\nif (removedExists && preventReactivation) throw new IllegalStateException(\"Removed rule exists: \" + key);","typeGuard":null,"tryCatchPattern":"try { ruleCreator.create(...); } catch (ReactivationException e) { log.warn(\"Removed rule blocks reactivation: {}\", e.ruleKey()); }","preventionTips":["Set preventReactivation=false when re-adding previously removed rules intentionally.","Track removed rule keys in bulk imports to avoid collisions."],"tags":["rules","reactivation","duplicate-key","quality-profiles"],"backgroundTag":"file-already-exists","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}