SonarSource/sonarqube · error · IllegalArgumentException
A version event already exists on analysis
Error message
A version event already exists on analysis '%s'
What it means
SonarQube throws this IllegalArgumentException from CreateEventAction.throwException when a client attempts to create a VERSION event on an analysis that already has one. An analysis can hold at most one version event, so the server rejects duplicates with a 400 response. The check runs against existing DB events for the target analysis before insert.
Solutions
- Check existing events first (GET api/events?analysis=<uuid>) and skip creation or delete the old version event (POST api/projects/delete_event) before creating a new one.
- Make the pipeline step idempotent: catch the 400 and treat 'version already exists' as success.
- Ensure each build creates a NEW analysis (e.g. correct CE report) rather than reusing an analysis uuid.
Example fix
// before
callCreateEvent(analysisUuid, "VERSION", "1.2.3"); // fails on retry
// after
List<Event> events = getEvents(analysisUuid);
Event existing = events.stream().filter(e -> "VERSION".equals(e.getCategory())).findFirst().orElse(null);
if (existing != null) {
deleteEvent(existing.getUuid());
}
callCreateEvent(analysisUuid, "VERSION", "1.2.3"); Defensive patterns
Strategy: validation
Validate before calling
List<Event> events = getEvents(analysisUuid); // GET api/events?analysis=<uuid>
boolean hasVersion = events.stream().anyMatch(e -> "VERSION".equals(e.getCategory()));
if (hasVersion) { /* skip create or delete existing first */ } Try / catch
try {
createEvent(analysisUuid, "VERSION", version);
} catch (FeignException | SonarQubeClientException e) {
if (String.valueOf(e.getMessage()).contains("version event already exists")) {
LOG.info("version event already present; treating as success");
} else throw e;
} Prevention
- Check existing events for the analysis before creating any event
- Make CI publish steps idempotent and safe to retry
- Never reuse analysis uuids across builds
When it happens
Trigger: POST api/projects/create_event with category=VERSION on an analysis uuid that already has a version event. Calling the API twice for the same analysis (double-click/retry of a non-idempotent call). Automation that publishes a version per build without checking for an existing one.
Common situations: CI pipelines re-running a publish step after a partial failure; scripts using the same analysis uuid; users manually creating a second 'Version' event in the UI for an analysis that already has one.
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
- An ' ' event with the same name already exists on analysis
- An ' ' event with the same name already exists on analysis
- An DevOps Platform setting with key
- Analysis ' ' not found
- Backup XML is not valid. Root element must be
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/36c3848d1b50d464.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/CreateEventAction.java:202
.ifPresent(throwException(request));
}
private static Predicate<EventDto> filterSimilarEvents(CreateEventRequest request) {
switch (request.getCategory()) {
case VERSION:
return dbEvent -> VERSION.getLabel().equals(dbEvent.getCategory());
case OTHER:
return dbEvent -> OTHER.getLabel().equals(dbEvent.getCategory()) && request.getName().equals(dbEvent.getName());
default:
throw new IllegalStateException("Event category not handled: " + request.getCategory());
}
}
private static Consumer<EventDto> throwException(CreateEventRequest request) {
switch (request.getCategory()) {
case VERSION:
return dbEvent -> {
throw new IllegalArgumentException(format("A version event already exists on analysis '%s'", request.getAnalysis()));
};
case OTHER:
return dbEvent -> {
throw new IllegalArgumentException(format("An '%s' event with the same name already exists on analysis '%s'", OTHER.getLabel(), request.getAnalysis()));
};
default:
throw new IllegalStateException("Event category not handled: " + request.getCategory());
}
}
private static class CreateEventRequest {
private final String analysis;
private final EventCategory category;
private final String name;
private CreateEventRequest(Builder builder) {
analysis = builder.analysis;
category = builder.category;View on GitHub (pinned to 184c821202)