immich-app/immich · error · BadRequestException
Storage label already in use by another account
Error message
Storage label already in use by another account
What it means
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.
Source
Thrown at server/src/services/user-admin.service.ts:78
throw new BadRequestException('Admin status can only be changed by another admin');
}
if (dto.quotaSizeInBytes && user.quotaSizeInBytes !== dto.quotaSizeInBytes) {
await this.userRepository.syncUsage(id);
}
if (dto.email) {
const duplicate = await this.userRepository.getByEmail(dto.email);
if (duplicate && duplicate.id !== id) {
this.logger.debug('Email already in use by another account');
throw new BadRequestException('Email is not available');
}
}
if (dto.storageLabel) {
const duplicate = await this.userRepository.getByStorageLabel(dto.storageLabel);
if (duplicate && duplicate.id !== id) {
throw new BadRequestException('Storage label already in use by another account');
}
}
if (dto.password) {
dto.password = await this.cryptoRepository.hashBcrypt(dto.password, SALT_ROUNDS);
}
if (dto.pinCode) {
dto.pinCode = await this.cryptoRepository.hashBcrypt(dto.pinCode, SALT_ROUNDS);
}
if (dto.storageLabel === '') {
dto.storageLabel = null;
}
const updatedUser = await this.userRepository.update(id, { ...dto, updatedAt: new Date() });
return mapUserAdmin(updatedUser);View on GitHub (pinned to 199723261c)
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.
Example fix
// before
await usersApi.update(id, { storageLabel: 'jane' }); // 'jane' taken
// after
await usersApi.update(otherId, { storageLabel: '' });
await usersApi.update(id, { storageLabel: 'jane' }); Defensive patterns
Strategy: validation
Validate before calling
const owner = await userRepository.getByStorageLabel(dto.storageLabel);
if (owner && owner.id !== id) { /* show 'label taken' error, do not PUT */ } Try / catch
try { await usersApi.update(id, dto); }
catch (e) {
if (e instanceof BadRequestException && /Storage label already in use/.test(e.message)) {
// clear the label on the other user, or choose a new label
}
} Prevention
- 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.
When it happens
Trigger: PUT /admin/users/:id with a storageLabel already assigned to a different account.
Common situations: Renaming a user and reusing their old label; consolidating two users under one label; clearing then re-assigning a label that was reused.
Related errors
- Email is not available
- A tag with that name already exists
- password is required
- Admin status can only be changed by another admin
- Quota has been exceeded!
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/cfeb8375601cf6c2.
Report an issue: GitHub.