{"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/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/user-admin.service.ts#L60-L96","documentation":"Thrown (as BadRequestException) by UserAdminService.update when dto.storageLabel is provided and userRepository.getByStorageLabel returns another user. Storage labels map to a unique on-disk subfolder, so duplicates are rejected before persistence to prevent asset path collisions.","triggerScenarios":"PUT /admin/users/:id with a storageLabel already assigned to a different account.","commonSituations":"Renaming a user and reusing their old label; consolidating two users under one label; clearing then re-assigning a label that was reused.","solutions":["Choose a storage label not currently in use (list users and their labels first).","Clear the label on the conflicting user (set to '' ) before assigning it here.","Leave storageLabel empty to let Immich use the user id as the folder."],"exampleFix":"// before\nawait usersApi.update(id, { storageLabel: 'jane' }); // 'jane' taken\n// after\nawait usersApi.update(otherId, { storageLabel: '' });\nawait usersApi.update(id, { storageLabel: 'jane' });","handlingStrategy":"validation","validationCode":"const owner = await userRepository.getByStorageLabel(dto.storageLabel);\nif (owner && owner.id !== id) { /* show 'label taken' error, do not PUT */ }","typeGuard":null,"tryCatchPattern":"try { await usersApi.update(id, dto); }\ncatch (e) {\n  if (e instanceof BadRequestException && /Storage label already in use/.test(e.message)) {\n    // clear the label on the other user, or choose a new label\n  }\n}","preventionTips":["List existing storage labels before letting an admin pick one.","Prefer leaving storageLabel empty (use user id) for new users.","When renaming a user, free the old label before assigning it elsewhere."],"tags":["users","storage","validation","duplicate","bad-request"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}