SonarSource/sonarqube · error · IllegalArgumentException

Rule ' ' can not use 'Constant/issue' remediation function…

Error message

Rule '%s' can not use 'Constant/issue' remediation function because this rule does not have a fixed remediation cost.

What it means

DebtCalculator.verifyEffortToFix() enforces that a rule using the CONSTANT_ISSUE (Constant/issue) remediation function must NOT have a gap/effortToFix set on the issue. If fn.type() is CONSTANT_ISSUE and issue.gap() != null, it throws IllegalArgumentException because the remediation cost is fixed by definition and a per-issue gap is contradictory.

Solutions

  1. Change the rule's remediation function from 'Constant/issue' to a gap-based one (e.g. 'Linear/offset' or 'Linear') if per-issue effort is intended
  2. Remove the gap/effortToFix computation in the sensor/plugin for rules with CONSTANT_ISSUE
  3. Update the rule metadata (remediationFunction/remediationGap) so it is consistent with what the analyzer reports

Example fix

// before: sensor sets gap on a CONSTANT_ISSUE rule
issue.setGap(5.0); // rule fn = CONSTANT_ISSUE -> throws
// after option A: drop the gap
// issue.gap left unset for constant-cost rules
// after option B: use a linear function in the rule definition
"remediationFunction": "LINEAR",
Defensive patterns

Strategy: type-guard

Validate before calling

// before invoking debt calculation
DebtRemediationFunction fn = rule.debtRemediationFunction();
if (fn != null && Type.CONSTANT_ISSUE.equals(fn.type()) && issue.gap() != null) {
  issue.setGap(null); // or use a linear function rule
}

Type guard

static boolean allowsGap(DebtRemediationFunction fn) {
  return fn == null || !Type.CONSTANT_ISSUE.equals(fn.type());
}
// guard: if (allowsGap(fn)) { issue.setGap(value); }

Try / catch

try {
  debt = debtCalculator.calculate(issue, rule);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("Constant/issue")) {
    issue.setGap(null); // constant-cost rule: gap must be unset
    debt = debtCalculator.calculate(issue, rule);
  } else throw e;
}

Prevention

When it happens

Trigger: calculate() processes an issue whose rule defines remediation function 'Constant/issue' while the analyzer report supplies effortToFix/gap for that issue — e.g. a custom rule or SonarQube plugin computes effort for a rule whose function declares a fixed cost.

Common situations: Custom rule authors setting CONSTANT_ISSUE in the rule definition while their sensor still calls issue.setGap(); rules whose remediation function was changed in a rule update while old issues carry gaps; third-party plugins with mismatched rule metadata.

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/ed035d8cefbc7b7b. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/DebtCalculator.java:70

      String gapMultiplier = fn.gapMultiplier();
      if (fn.type().usesGapMultiplier() && !Strings.isNullOrEmpty(gapMultiplier)) {
        int effortToFixValue = MoreObjects.firstNonNull(issue.gap(), 1).intValue();
        // TODO convert to Duration directly in Rule#remediationFunction -> better performance + error handling
        debt = durations.decode(gapMultiplier).multiply(effortToFixValue);
      }
      String baseEffort = fn.baseEffort();
      if (fn.type().usesBaseEffort() && !Strings.isNullOrEmpty(baseEffort)) {
        // TODO convert to Duration directly in Rule#remediationFunction -> better performance + error handling
        debt = debt.add(durations.decode(baseEffort));
      }
      return debt;
    }
    return null;
  }

  private static void verifyEffortToFix(DefaultIssue issue, DebtRemediationFunction fn) {
    if (Type.CONSTANT_ISSUE.equals(fn.type()) && issue.gap() != null) {
      throw new IllegalArgumentException("Rule '" + issue.getRuleKey() + "' can not use 'Constant/issue' remediation function " +
        "because this rule does not have a fixed remediation cost.");
    }
  }
}

View on GitHub (pinned to 184c821202)