flowable/flowable-engine · error · FlowableConflictException
A group with id '' already exists.
Error message
A group with id '' already exists.
What it means
createGroup checks identityService.createGroupQuery().groupId(id).count() before creating, and throws FlowableConflictException when a group with that id already exists. This pre-check exists because the underlying identity API does not throw a typed duplicate-key exception, so the REST layer maps it to HTTP 409.
Solutions
- Check existence first (GET /identity/groups/{id}) and skip or update instead of POSTing a duplicate.
- Make seed scripts idempotent: create only when the group is absent.
- If the existing group should receive new attributes, use PUT /identity/groups/{id} rather than POST.
Example fix
// before
client.post("/identity/groups", group); // may 409 on retry
// after
if (client.get("/identity/groups/" + group.getId()) == null) {
client.post("/identity/groups", group);
} else {
client.put("/identity/groups/" + group.getId(), group);
} Defensive patterns
Strategy: validation
Validate before calling
boolean exists = client.list("/identity/groups").stream()
.anyMatch(g -> groupRequest.getId().equals(g.getId()));
if (exists) { /* update or skip instead of POST */ } Try / catch
try {
client.post("/identity/groups", groupRequest);
} catch (HttpClientErrorException e) {
if (e.getStatusCode() == HttpStatus.CONFLICT) {
client.put("/identity/groups/" + groupRequest.getId(), groupRequest); // upsert
} else throw e;
} Prevention
- Make bootstrap/seed scripts idempotent.
- Use PUT for attribute updates, POST only for creation.
- Serialize concurrent group creation behind a single admin workflow.
When it happens
Trigger: POST /identity/groups with an "id" that already exists in ACT_ID_GROUP, including a retry of a successful create or a re-seeded demo group id such as from the Flowable demo data setup.
Common situations: Non-idempotent bootstrap/seed scripts run twice; race between two admins creating the same group concurrently; migration script re-inserting groups from an old system without checking existence.
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
- Engine property already exists
- User '' is already part of group ''.
- Variable ' ' is already present on task ' '.
- Could not find a group with id ''.
- Id cannot be null.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/a9cdcb501716a438.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/identity/GroupCollectionResource.java:133
@ApiOperation(value = "Create a group", tags = { "Groups" }, code = 201)
@ApiResponses(value = {
@ApiResponse(code = 201, message = "Indicates the group was created."),
@ApiResponse(code = 400, message = "Indicates the id of the group was missing.")
})
@PostMapping(value = "/identity/groups", produces = "application/json")
@ResponseStatus(HttpStatus.CREATED)
public GroupResponse createGroup(@RequestBody GroupRequest groupRequest) {
if (groupRequest.getId() == null) {
throw new FlowableIllegalArgumentException("Id cannot be null.");
}
if (restApiInterceptor != null) {
restApiInterceptor.createGroup(groupRequest);
}
// Check if a user with the given ID already exists so we return a CONFLICT
if (identityService.createGroupQuery().groupId(groupRequest.getId()).count() > 0) {
throw new FlowableConflictException("A group with id '" + groupRequest.getId() + "' already exists.");
}
Group created = identityService.newGroup(groupRequest.getId());
created.setId(groupRequest.getId());
created.setName(groupRequest.getName());
created.setType(groupRequest.getType());
identityService.saveGroup(created);
return restResponseFactory.createGroupResponse(created);
}
}
View on GitHub (pinned to d6d39ce1c6)