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
- Identify the unexpected root component type from the stack trace/component key
- Disable or update the plugin that creates the unsupported root component type
- Upgrade to a SonarQube version where the new component type is supported by history recording
- 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
- Only feed supported root component types (PROJECT, VIEW/APPLICATION/PORTFOLIO) into the computation tree
- Update RecordHistoryStep whenever a new Component.Type is introduced
- Keep portfolio/view plugins version-aligned with the server
- Log root component type early in the pipeline to catch bad trees sooner
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
- Unsupported value '%s' of Measure.Level can not be converted
- Unsupported value '%s' of Measure.Level can not be converted
- Only http and https schemes are supported
- Github configuration is not complete. Please check your conf
- Configuration is not complete : %s
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/766cc7b323952268.
Report an issue: GitHub.