immich-app/immich · warning · BadRequestException
Invalid albumId
Error message
Invalid albumId
What it means
In SharedLinkService.create(), for SharedLinkType.Album the service requires dto.albumId to be present; a missing/empty albumId throws BadRequestException 'Invalid albumId' (shared-link.service.ts:73, HTTP 400) before any access check.
Source
Thrown at server/src/services/shared-link.service.ts:73
const { id, password } = sharedLink;
if (password && !authTokens.includes(this.asToken({ id, password }))) {
throw new UnauthorizedException('Password required');
}
return mapSharedLink(sharedLink, { stripAssetMetadata: !sharedLink.showExif });
}
async get(auth: AuthDto, id: string): Promise<SharedLinkResponseDto> {
const sharedLink = await this.findOrFail(auth.user.id, id);
return mapSharedLink(sharedLink, { stripAssetMetadata: false });
}
async create(auth: AuthDto, dto: SharedLinkCreateDto): Promise<SharedLinkResponseDto> {
switch (dto.type) {
case SharedLinkType.Album: {
if (!dto.albumId) {
throw new BadRequestException('Invalid albumId');
}
await this.requireAccess({ auth, permission: Permission.AlbumShare, ids: [dto.albumId] });
break;
}
case SharedLinkType.Individual: {
if (!dto.assetIds || dto.assetIds.length === 0) {
throw new BadRequestException('Invalid assetIds');
}
await this.requireAccess({ auth, permission: Permission.AssetShare, ids: dto.assetIds });
break;
}
}
try {
const sharedLink = await this.sharedLinkRepository.create({View on GitHub (pinned to 199723261c)
Solutions
- Set dto.albumId to a valid existing album UUID when type is Album.
- On the client, disable the 'create shared link' action until an album is selected.
- Validate the DTO shape before sending.
Example fix
// before
await create({ type: SharedLinkType.Album });
// after
await create({ type: SharedLinkType.Album, albumId }); Defensive patterns
Strategy: validation
Validate before calling
if (dto.type === SharedLinkType.Album && !dto.albumId) {
throw new Error('albumId is required for album shared links.');
}
await sharedLinkApi.create(dto); Type guard
const isValidAlbumCreate = (dto: SharedLinkCreateDto): boolean => dto.type !== SharedLinkType.Album || !!dto.albumId;
Try / catch
try {
await sharedLinkApi.create(dto);
} catch (e) {
if (e instanceof BadRequestException && /albumId/i.test(e.message)) {
promptAlbumSelection();
} else throw e;
} Prevention
- Disable the create-album-share action until an album is selected.
- Build the DTO from the current selection state, not stale values.
When it happens
Trigger: POST /shared-links with type=Album but albumId omitted/null/empty string. Creating an album shared link requires identifying which album to share.
Common situations: Client building the DTO from an album list selection where the user hadn't picked an album, or a refactor that dropped the albumId field.
Related errors
- Shared link access is only allowed in combination with an al
- Invalid assetIds
- Either `query` or `queryAssetId` must be set
- No fields to update
- Shared link is not password protected
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/c658a45b75c50202.
Report an issue: GitHub.