SonarSource/sonarqube · error · IllegalArgumentException

A rule with the key ' ' already exists

Error message

A rule with the key '%s' already exists

What it means

RuleCreator.updateExistingRule throws this IllegalArgumentException when an update operation reaches the 'create' branch of the rule creation logic, meaning a rule with the given key already exists in the database. It guards against inserting a duplicate rule key when the caller expected to create a new rule.

Solutions

  1. Check rule existence first via api/rules/show?key=... or RuleDao.selectRuleByKey and use the update endpoint (api/rules/update) instead of create.
  2. Make provisioning scripts idempotent: create if absent, update if present.
  3. Use a different, unique rule key if you truly intend a new rule.
  4. Serialize rule provisioning so concurrent jobs cannot race on the same key.

Example fix

// before
ruleUpdater.create(createRequest); // fails when key exists
// after
if (ruleDao.selectRuleByKey(dbSession, key).isPresent()) {
  ruleUpdater.update(updateRequest);
} else {
  ruleUpdater.create(createRequest);
}
Defensive patterns

Strategy: validation

Validate before calling

RuleDto existing = dbClient.ruleDao().selectRuleByKey(dbSession, key).orElse(null);
if (existing != null) { /* update instead of create */ }

Try / catch

try { creator.create(req); } catch (IllegalArgumentException e) { if (e.getMessage().contains("already exists")) { updater.update(toUpdate(req)); } else { throw e; } }

Prevention

When it happens

Trigger: Calling the rules/create WS (or RuleCreator.create) with a rule key that already exists in the rule table, so the DAO lookup finds an existing ruleDto and control falls into the else branch that throws.

Common situations: Re-running an automation script that provisions custom rules without idempotency checks; importing a rules profile that already defines the rule; two CI jobs creating the same custom rule concurrently.

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


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/d0227ca98797b812. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-webserver-common/src/main/java/org/sonar/server/common/rule/RuleCreator.java:292

      } 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 {
      throw new IllegalArgumentException(format("A rule with the key '%s' already exists", ruleDto.getKey().rule()));
    }
    return ruleDto;
  }

}

View on GitHub (pinned to 184c821202)