{"record":{"id":"cfeb8375601cf6c2","repo":"immich-app/immich","slug":"storage-label-already-in-use-by-another-account","errorCode":null,"errorMessage":"Storage label already in use by another account","messagePattern":"Storage label already in use by another account","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/user-admin.service.ts","lineNumber":78,"sourceCode":"      throw new BadRequestException('Admin status can only be changed by another admin');\n    }\n\n    if (dto.quotaSizeInBytes && user.quotaSizeInBytes !== dto.quotaSizeInBytes) {\n      await this.userRepository.syncUsage(id);\n    }\n\n    if (dto.email) {\n      const duplicate = await this.userRepository.getByEmail(dto.email);\n      if (duplicate && duplicate.id !== id) {\n        this.logger.debug('Email already in use by another account');\n        throw new BadRequestException('Email is not available');\n      }\n    }\n\n    if (dto.storageLabel) {\n      const duplicate = await this.userRepository.getByStorageLabel(dto.storageLabel);\n      if (duplicate && duplicate.id !== id) {\n        throw new BadRequestException('Storage label already in use by another account');\n      }\n    }\n\n    if (dto.password) {\n      dto.password = await this.cryptoRepository.hashBcrypt(dto.password, SALT_ROUNDS);\n    }\n\n    if (dto.pinCode) {\n      dto.pinCode = await this.cryptoRepository.hashBcrypt(dto.pinCode, SALT_ROUNDS);\n    }\n\n    if (dto.storageLabel === '') {\n      dto.storageLabel = null;\n    }\n\n    const updatedUser = await this.userRepository.update(id, { ...dto, updatedAt: new Date() });\n\n    return mapUserAdmin(updatedUser);","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/services/user-admin.service.ts#L60-L96","documentation":"Thrown by UserAdminService.update when the requested storageLabel is already assigned to a different account. Storage labels map users to unique storage paths, so duplicates would collide on disk layout. It is a 400 BadRequest for a uniqueness conflict.","triggerScenarios":"PUT/PATCH /api/admin/users/:id with dto.storageLabel matching another user's storage label (duplicate.id !== id). Common when copying storage labels between users or reusing a label from a deleted account that still holds it.","commonSituations":"Migration scripts assigning external-library storage paths; an admin reusing an old employee's storage label for a new hire while the old account remains; typos where two users get the same label.","solutions":["Pick a unique storage label for the user","Clear the label from the conflicting account first, then assign it","Query users by storageLabel before assignment to verify availability"],"exampleFix":"// before\nawait adminApi.updateUser(newUser.id, { storageLabel: oldEmployeeLabel });\n// after\nconst taken = users.find(u => u.storageLabel === oldEmployeeLabel && u.id !== newUser.id);\nconst label = taken ? `${oldEmployeeLabel}-2` : oldEmployeeLabel;\nawait adminApi.updateUser(newUser.id, { storageLabel: label });","handlingStrategy":"validation","validationCode":"const taken = users.find(u => u.storageLabel === dto.storageLabel && u.id !== id);\nif (taken) {\n  throw new Error(`storage label ${dto.storageLabel} already in use`);\n}","typeGuard":null,"tryCatchPattern":"try { await adminApi.updateUser(id, dto); } catch (e) {\n  if (e.response?.status === 400 && /Storage label already/.test(e.response?.data?.message ?? '')) {\n    // pick a unique label or clear it on the conflicting account\n  }\n  throw e;\n}","preventionTips":["Keep a registry of assigned storage labels","Generate labels from usernames with a uniqueness suffix","Audit labels after deletions/migrations"],"tags":["duplicate","uniqueness","storage"],"backgroundTag":"record-already-exists","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"}