SonarSource/sonarqube · error · ReactivationException
A removed rule with the key
Error message
A removed rule with the key '%s' already exists
What it means
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.
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.
Example fix
// before POST /api/rules/create?custom_key=old-rule&prevent_reactivation=true (removed rule 'old-rule' exists) // after POST /api/rules/create?custom_key=old-rule&prevent_reactivation=false
Defensive patterns
Strategy: try-catch
Validate before calling
// check for existing removed rule before create
RuleDto existing = dbClient.ruleDao().selectByKey(dbSession, RuleKey.of(repo, key));
boolean removedExists = existing != null && RuleStatus.REMOVED.equals(existing.getStatus());
if (removedExists && preventReactivation) throw new IllegalStateException("Removed rule exists: " + key); Try / catch
try { ruleCreator.create(...); } catch (ReactivationException e) { log.warn("Removed rule blocks reactivation: {}", e.ruleKey()); } Prevention
- Set preventReactivation=false when re-adding previously removed rules intentionally.
- Track removed rule keys in bulk imports to avoid collisions.
When it happens
Trigger: Creating (or reactivating) a custom rule via api/rules/create with preventReactivation=true while a rule with the same key exists in REMOVED status.
Common situations: 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.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- A rule with the key ' ' already exists
- Specified RuleKey ' ' is not equal to the one already…
- An DevOps Platform setting with key
- Both 'severity' and 'impacts' parameters cannot be set at…
- Could not retrieve rule with uuid
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/11dcf3b969d5beec.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/RuleCreator.java:273
.setType(type)
.setSeverity(severity);
}
}
}
private void createCustomRuleParams(@Nullable String paramValue, RuleDto ruleDto, RuleParamDto templateRuleParam, DbSession dbSession) {
RuleParamDto ruleParamDto = RuleParamDto.createFor(ruleDto)
.setName(templateRuleParam.getName())
.setType(templateRuleParam.getType())
.setDescription(templateRuleParam.getDescription())
.setDefaultValue(paramValue);
dbClient.ruleDao().insertRuleParam(dbSession, ruleDto, ruleParamDto);
}
private RuleDto updateExistingRule(RuleDto ruleDto, NewCustomRule newRule, RuleDto templateRule, DbSession dbSession) {
if (ruleDto.getStatus().equals(RuleStatus.REMOVED)) {
if (newRule.isPreventReactivation()) {
throw new ReactivationException(format("A removed rule with the key '%s' already exists", ruleDto.getKey().rule()), ruleDto.getKey());
} else {
ruleDto.setStatus(RuleStatus.READY)
.setName(newRule.name())
.replaceRuleDescriptionSectionDtos(Set.of(
createDefaultRuleDescriptionSection(uuidFactory.create(), newRule.markdownDescription())))
.setUpdatedAt(system2.now());
ruleDto.replaceAllDefaultImpacts(Set.of());
setCleanCodeAttributeAndImpacts(newRule, ruleDto, templateRule);
dbClient.ruleDao().update(dbSession, ruleDto);
for (RuleParamDto ruleParamDto : dbClient.ruleDao().selectRuleParamsByRuleKey(dbSession, ruleDto.getKey())) {
String newValue = Strings.emptyToNull(newRule.parameter(ruleParamDto.getName()));
ruleParamDto.setDefaultValue(newValue);
dbClient.ruleDao().updateRuleParam(dbSession, ruleDto, ruleParamDto);
}
}
} else {View on GitHub (pinned to 184c821202)