{"record":{"id":"be0416f0ac8257cd","repo":"SonarSource/sonarqube","slug":"an-s-event-with-the-same-name-already-exists-on-be0416","errorCode":null,"errorMessage":"An '%s' event with the same name already exists on analysis '%s'","messagePattern":"An '(.+?)' event with the same name already exists on analysis '(.+?)'","errorType":"http","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java","lineNumber":145,"sourceCode":"  private EventDto getDbEvent(DbSession dbSession, UpdateEventRequest request) {\n    checkArgument(isNotBlank(request.getName()), \"A non empty name is required\");\n    return dbClient.eventDao().selectByUuid(dbSession, request.getEvent())\n      .orElseThrow(() -> new NotFoundException(format(\"Event '%s' not found\", request.getEvent())));\n  }\n\n  private Consumer<EventDto> checkPermissions() {\n    return event -> userSession.checkComponentUuidPermission(ProjectPermission.ADMIN, event.getComponentUuid());\n  }\n\n  private Consumer<EventDto> checkNonConflictingOtherEvents(DbSession dbSession) {\n    return candidateEvent -> {\n      List<EventDto> dbEvents = dbClient.eventDao().selectByAnalysisUuid(dbSession, candidateEvent.getAnalysisUuid());\n      Predicate<EventDto> otherEventWithSameName = otherEvent -> !candidateEvent.getUuid().equals(otherEvent.getUuid()) && otherEvent.getName().equals(candidateEvent.getName());\n      dbEvents.stream()\n        .filter(otherEventWithSameName)\n        .findAny()\n        .ifPresent(event -> {\n          throw new IllegalArgumentException(format(\"An '%s' event with the same name already exists on analysis '%s'\",\n            candidateEvent.getCategory(),\n            candidateEvent.getAnalysisUuid()));\n        });\n    };\n  }\n\n  private static Consumer<EventDto> checkVersionNameLength(UpdateEventRequest request) {\n    return candidateEvent -> checkVersionName(candidateEvent.getCategory(), request.getName());\n  }\n\n  private SnapshotDto getAnalysis(DbSession dbSession, EventDto event) {\n    return dbClient.snapshotDao().selectByUuid(dbSession, event.getAnalysisUuid())\n      .orElseThrow(() -> new IllegalStateException(format(\"Analysis '%s' is not found\", event.getAnalysisUuid())));\n  }\n\n  private static Function<EventDto, EventDto> updateNameAndDescription(UpdateEventRequest request) {\n    return event -> {\n      ofNullable(request.getName()).ifPresent(event::setName);","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/UpdateEventAction.java#L127-L163","documentation":"UpdateEventAction.checkNonConflictingOtherEvents rejects an event update if any OTHER event on the same analysis — other than the one being updated — already has the same name. This enforces name uniqueness of OTHER events per analysis and is raised as IllegalArgumentException (HTTP 400).","triggerScenarios":"POST api/projects/update_event renaming (or keeping) an event's name to one that collides with a sibling event on the same analysis uuid. Merging event histories where two events share a name.","commonSituations":"Bulk scripts that normalize event names; importing events where two status-change entries were recorded with identical names; UI/API race where another user created the same-named event first.","solutions":["Fetch events on the analysis (GET api/events?analysis=<uuid>) and pick a unique name before updating.","Delete the conflicting sibling event if it is redundant.","Append a distinguishing suffix (timestamp/sequence) to the event name.","Handle 400 in scripts by regenerating a unique name and retrying once."],"exampleFix":"// before\nupdateEvent(eventUuid, \"Quality gate changed\"); // 400 on name clash\n// after\nString name = \"Quality gate changed\";\nboolean clash = getEvents(analysisUuid).stream()\n  .anyMatch(e -> !eventUuid.equals(e.getUuid()) && name.equals(e.getName()));\nif (clash) {\n  name = name + \" (\" + Instant.now() + \")\";\n}\nupdateEvent(eventUuid, name);","handlingStrategy":"validation","validationCode":"String newName = candidateName;\nSet<String> taken = getEvents(analysisUuid).stream()\n  .filter(e -> !eventUuid.equals(e.getUuid()))\n  .map(Event::getName)\n  .collect(Collectors.toSet());\nwhile (taken.contains(newName)) { newName = candidateName + \"-\" + System.currentTimeMillis(); }","typeGuard":null,"tryCatchPattern":"try {\n  updateEvent(eventUuid, newName);\n} catch (SonarQubeClientException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"with the same name already exists\")) {\n    updateEvent(eventUuid, newName + \"-\" + System.currentTimeMillis());\n  } else throw e;\n}","preventionTips":["Enumerate sibling events on the analysis before renaming","Use names with built-in uniqueness (timestamps, build numbers)","Serialize event-management scripts to avoid concurrent creation"],"tags":["sonarqube","webapi","duplicate-resource","events","name-conflict"],"backgroundTag":"file-already-exists","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}