immich-app/immich · warning · BadRequestException
Invalid assetIds
Error message
Invalid assetIds
What it means
In SharedLinkService.create(), for SharedLinkType.Individual the service requires dto.assetIds to be a non-empty array; otherwise it throws BadRequestException 'Invalid assetIds' (shared-link.service.ts:81, HTTP 400) before access checks.
Source
Thrown at server/src/services/shared-link.service.ts:81
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({
key: this.cryptoRepository.randomBytes(50),
userId: auth.user.id,
type: dto.type,
albumId: dto.albumId || null,
assetIds: dto.assetIds,
description: dto.description || null,
password: dto.password,
expiresAt: dto.expiresAt || null,View on GitHub (pinned to 199723261c)
Solutions
- Provide at least one asset id in dto.assetIds when type is Individual.
- Disable the share action until at least one asset is selected.
- Validate the array is non-empty on the client before submitting.
Example fix
// before
await create({ type: SharedLinkType.Individual, assetIds: [] });
// after
await create({ type: SharedLinkType.Individual, assetIds: [assetId] }); Defensive patterns
Strategy: validation
Validate before calling
if (dto.type === SharedLinkType.Individual && (!dto.assetIds || dto.assetIds.length === 0)) {
throw new Error('At least one assetId is required for individual shared links.');
}
await sharedLinkApi.create(dto); Type guard
const hasAssetIds = (dto: SharedLinkCreateDto): boolean => dto.type !== SharedLinkType.Individual || (Array.isArray(dto.assetIds) && dto.assetIds.length > 0);
Try / catch
try {
await sharedLinkApi.create(dto);
} catch (e) {
if (e instanceof BadRequestException && /assetIds/i.test(e.message)) {
promptAssetSelection();
} else throw e;
} Prevention
- Require a non-empty asset selection before enabling the share action.
- Validate the DTO array length client-side.
When it happens
Trigger: POST /shared-links with type=Individual but assetIds missing, null, or an empty array. An individual shared link must reference at least one asset.
Common situations: Creating a share from an empty selection, the selection state being cleared before the create call, or a bulk action invoked with no assets checked.
Related errors
- Invalid albumId
- Invalid shared link type
- May not request original file
- Asset not found or asset is not a video
- Both assets must exist
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/af69042f5bcaed61.
Report an issue: GitHub.