immich-app/immich · warning · BadRequestException
Editing GIF images is not supported
Error message
Editing GIF images is not supported
What it means
Thrown by editAsset when asset.originalPath ends with '.gif' (case-insensitive). GIFs are animated/animated-container images that the raster editor cannot transform safely, so they are rejected with 400 BadRequest before edits are applied.
Source
Thrown at server/src/services/asset.service.ts:548
const asset = await this.assetRepository.getForEdit(id);
if (!asset) {
throw new BadRequestException('Asset not found');
}
if (asset.type !== AssetType.Image) {
throw new BadRequestException('Only images can be edited');
}
if (asset.livePhotoVideoId) {
throw new BadRequestException('Editing live photos is not supported');
}
if (isPanorama(asset)) {
throw new BadRequestException('Editing panorama images is not supported');
}
if (asset.originalPath?.toLowerCase().endsWith('.gif')) {
throw new BadRequestException('Editing GIF images is not supported');
}
if (asset.originalPath?.toLowerCase().endsWith('.svg')) {
throw new BadRequestException('Editing SVG images is not supported');
}
// check that crop parameters will not go out of bounds
const { width: assetWidth, height: assetHeight } = getDimensions(asset);
if (!assetWidth || !assetHeight) {
throw new BadRequestException('Asset dimensions are not available for editing');
}
const edits = dto.edits as AssetEditActionItem[];
const crop = edits.find((e) => e.action === AssetEditAction.Crop);
if (crop) {
if (edits[0].action !== AssetEditAction.Crop) {
throw new BadRequestException('Crop action must be the first edit action');View on GitHub (pinned to 199723261c)
Solutions
- Disable the editor for assets whose originalPath/originalFileName ends in .gif (case-insensitive).
- Convert the GIF to a static PNG/JPEG asset first if a single-frame edit is required.
Example fix
// before
const editable = asset.type === 'IMAGE';
// after
const path = (asset.originalPath ?? asset.originalFileName ?? '').toLowerCase();
const editable = asset.type === 'IMAGE' && !path.endsWith('.gif'); Defensive patterns
Strategy: validation
Validate before calling
const path = (asset.originalPath ?? asset.originalFileName ?? '').toLowerCase();
if (path.endsWith('.gif')) {
throw new Error('GIF assets cannot be edited.');
}
await api.put(`/assets/${asset.id}/edits`, { edits }); Type guard
const isGif = (a: { originalPath?: string; originalFileName?: string }): boolean =>
(a?.originalPath ?? a?.originalFileName ?? '').toLowerCase().endsWith('.gif'); Prevention
- Lowercase the path before comparing; the server lowercases too.
- Hide the editor for .gif assets.
- Convert GIFs to a static frame if pixel editing is needed.
When it happens
Trigger: PUT /assets/{id}/edits on an asset whose stored originalPath has a .gif extension.
Common situations: User imports GIFs alongside photos; client enables editing without checking extension; case-variant .GIF uploads that get lowercased by the path check.
Related errors
- Only images can be edited
- Editing panorama images is not supported
- Editing SVG images is not supported
- Asset dimensions are not available for editing
- Editing live photos is not supported
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/b3e2b3e6ba428af5.
Report an issue: GitHub.