{"record":{"id":"80f05695ac124a9f","repo":"immich-app/immich","slug":"cannot-leave-a-cluster-group-without-any-other-mem","errorCode":null,"errorMessage":"Cannot leave a cluster group without any other members","messagePattern":"Cannot leave a cluster group without any other members","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"server/src/services/cluster-group.service.ts","lineNumber":92,"sourceCode":"\n  async regeneratePeople(auth: AuthDto, id: string) {\n    await this.requireAccess({ auth, permission: Permission.ClusterGroupRead, ids: [id] });\n\n    await this.jobRepository.queue({\n      name: JobName.FacialRecognitionQueueAll,\n      data: { clusterGroupId: id, force: true },\n    });\n  }\n\n  async leave(auth: AuthDto, clusterGroupId: string): Promise<void> {\n    await this.requireAccess({ auth, permission: Permission.ClusterGroupLeave, ids: [clusterGroupId] });\n\n    const hasOtherMembers = await this.clusterGroupRepository.hasOtherMembers({\n      clusterGroupId,\n      userId: auth.user.id,\n    });\n    if (!hasOtherMembers) {\n      throw new BadRequestException('Cannot leave a cluster group without any other members');\n    }\n\n    const clusterGroup = await this.clusterGroupRepository.create();\n    await this.personRepository.reassignCluster({ userId: auth.user.id, newClusterId: clusterGroup.id });\n    await this.userRepository.update(auth.user.id, { clusterGroupId: clusterGroup.id });\n  }\n}\n","sourceCodeStart":74,"sourceCodeEnd":100,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/services/cluster-group.service.ts#L74-L100","documentation":"Leaving a cluster group is only allowed when at least one other member remains. The service queries clusterGroupRepository.hasOtherMembers and throws this BadRequestException if the caller is the sole member, since removing the last member would orphan the group.","triggerScenarios":"Calling the leave-cluster-group endpoint while your account is the only member of the group (hasOtherMembers returns false).","commonSituations":"A test/private cluster group created with just one user; other members removed earlier leaving you alone; trying to disband a group via the leave action instead of group deletion.","solutions":["Add another member to the group before leaving.","Delete/disband the group through the group management endpoint instead of leaving it.","Verify group membership count first and show a different UI flow for single-member groups."],"exampleFix":"// before\nawait api.leaveClusterGroup(groupId); // sole member → error\n// after\nawait api.addClusterGroupMember(groupId, otherUserId); // ensure another member exists\nawait api.leaveClusterGroup(groupId);","handlingStrategy":"try-catch","validationCode":"// Check remaining members before leaving\nconst members = await api.getClusterGroupMembers(groupId);\nconst others = members.filter(m => m.id !== currentUserId);\nif (others.length === 0) {\n  // disband group instead of leaving\n}","typeGuard":null,"tryCatchPattern":"try {\n  await api.leaveClusterGroup(groupId);\n} catch (e) {\n  if (e.response?.data?.message === 'Cannot leave a cluster group without any other members') {\n    await api.deleteClusterGroup(groupId); // or add a member first\n  } else throw e;\n}","preventionTips":["Check member count before offering the Leave action in UI.","Promote/add a replacement member before the last admin-owner leaves.","Offer explicit group deletion for single-member groups."],"tags":["cluster-group","bad-request","precondition","membership"],"backgroundTag":"invalid-state-transition","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}