SonarSource/sonarqube · warning · IllegalArgumentException

Source and target profiles are equal: %s

Error message

Source and target profiles are equal: %s

What it means

QProfileCopier.verify throws IllegalArgumentException when the source and target quality profile names are identical, since copying a profile onto itself is a no-op with undefined semantics. It fires early in prepareTarget before any copy work is done.

Source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualityprofile/QProfileCopier.java:59

    QProfileDto to = prepareTarget(dbSession, sourceProfile, toName);
    backuper.copy(dbSession, sourceProfile, to);
    return to;
  }

  private QProfileDto prepareTarget(DbSession dbSession, QProfileDto sourceProfile, String toName) {
    verify(sourceProfile.getName(), toName);
    QProfileName toProfileName = new QProfileName(sourceProfile.getLanguage(), toName);
    QProfileDto toProfile = db.qualityProfileDao().selectByNameAndLanguage(dbSession, toProfileName.getName(), toProfileName.getLanguage());
    if (toProfile == null) {
      toProfile = factory.createCustom(dbSession, toProfileName, sourceProfile.getParentKee());
      dbSession.commit();
    }
    return toProfile;
  }

  private static void verify(String fromProfileName, String toProfileName) {
    if (fromProfileName.equals(toProfileName)) {
      throw new IllegalArgumentException(String.format("Source and target profiles are equal: %s", toProfileName));
    }
  }
}

View on GitHub (pinned to 184c821202)

Solutions

  1. Provide a distinct toQualityProfile name in the copy request.
  2. Guard the caller: compare names and skip the API call (or no-op intentionally) when they are equal.
  3. Fix the templating/script variable that produced identical source and target names.

Example fix

// before
copyProfile(fromName, fromName); // 400: profiles are equal
// after
if (!fromName.equals(toName)) {
  copyProfile(fromName, toName);
} else {
  LOG.info("skip copy: source equals target");
}
Defensive patterns

Strategy: validation

Validate before calling

if (fromName.equals(toName)) {
  LOG.info("skip profile copy: source and target are identical");
  return;
}

Try / catch

try {
  copyProfile(fromName, toName);
} catch (SonarQubeClientException e) {
  if (String.valueOf(e.getMessage()).contains("Source and target profiles are equal")) {
    LOG.warn("copy skipped: identical profile names");
  } else throw e;
}

Prevention

When it happens

Trigger: POST api/qualityprofiles/copy with fromQualityProfile equal to toQualityProfile (same name). Provisioning scripts templating the target name from the source name without overriding it.

Common situations: Config templates where the destination variable was left empty and defaulted to the source name; scripted profile duplication loops with an off-by-one name mapping; manual API misuse copying a profile to itself.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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