SonarSource/sonarqube · error · IllegalArgumentException

History cannot be recorded for root component type

Error message

History cannot be recorded for root component type 

What it means

RecordHistoryStep records measure history for the analysis root. It maps the root component type to a history EntityType: PROJECT (or branches) map to PROJECT_BRANCH and views map to APPLICATION/PORTFOLIO. Any other root component type has no history representation, so getEntityType throws an IllegalArgumentException.

Source

Thrown at server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/RecordHistoryStep.java:72

  public void execute(ComputationStep.Context context) {
    Component root = treeRootHolder.getRoot();
    EntityType entityType = getEntityType(root);

    if (entityType == EntityType.APPLICATION || entityType == EntityType.PROJECT_BRANCH) {
      recordHistoryForEntity(root, entityType, getIssueSourceBranchUuids(root));
    } else {
      recordHistoryForEntity(root, EntityType.PORTFOLIO, collectChildBranchUuidsAndRecordSubtreeHistory(root, true));
    }
  }

  private static EntityType getEntityType(Component root) {
    return switch(root.getType()) {
      case PROJECT -> EntityType.PROJECT_BRANCH;
      case VIEW -> switch (root.getViewAttributes().getType()) {
        case APPLICATION -> EntityType.APPLICATION;
        case PORTFOLIO -> EntityType.PORTFOLIO;
      };
      default -> throw new IllegalArgumentException("History cannot be recorded for root component type " + root.getType());
    };
  }

  /**
   * Collects all child branch UUIDs by traversing the entire portfolio tree depth-first, recording history for each subtree if necessary.
   */
  private Set<String> collectChildBranchUuidsAndRecordSubtreeHistory(Component component, boolean recordSubtreeHistory) {
    Set<String> branchUuids = new HashSet<>();
    for (var child : component.getChildren()) {
      boolean recordChildHistory = recordSubtreeHistory && isNativeSubportfolio(child);
      Set<String> childBranchUuids = collectChildBranchUuidsAndRecordSubtreeHistory(child, recordChildHistory);
      branchUuids.addAll(childBranchUuids);
      if (recordChildHistory) {
        recordHistoryForEntity(child, EntityType.PORTFOLIO, childBranchUuids);
      }
    }
    if (component.getType() == PROJECT_VIEW) {
      branchUuids.add(component.getProjectViewAttributes().getUuid());

View on GitHub (pinned to 184c821202)

Solutions

  1. Identify the unexpected root component type from the stack trace/component key
  2. Disable or update the plugin that creates the unsupported root component type
  3. Upgrade to a SonarQube version where the new component type is supported by history recording
  4. Report a bug if the root is a standard project/view and the type is legitimately supported
Defensive patterns

Strategy: type-guard

Validate before calling

if (root.getType() != Component.Type.PROJECT && root.getType() != Component.Type.VIEW) {
  throw new IllegalStateException("History unsupported for root type: " + root.getType());
}

Type guard

Optional<EntityType> entityTypeOf(Component root) {
  return switch (root.getType()) {
    case PROJECT -> Optional.of(EntityType.PROJECT_BRANCH);
    case VIEW -> Optional.of(switch (root.getViewAttributes().getType()) {
      case APPLICATION -> EntityType.APPLICATION;
      case PORTFOLIO -> EntityType.PORTFOLIO;
    });
    default -> Optional.empty();
  };
}

Try / catch

try {
  EntityType t = entityType(root);
} catch (IllegalArgumentException e) {
  LOGGER.warn("Skipping history for unsupported root: {}", root.getKey(), e);
}

Prevention

When it happens

Trigger: entityType() -> getEntityType(root) is called with a root component whose type is not PROJECT and not a VIEW (with APPLICATION or PORTFOLIO view attributes) — e.g. a root of an unsupported type was fed into the computation tree.

Common situations: Plugins (e.g. governance/portfolio plugins) injecting custom root component types; version mismatch where a new Component.Type was added without updating this step; corrupted component tree during report processing.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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