immich-app/immich · error · BadRequestException

Editing GIF images is not supported

Error message

Editing GIF images is not supported

What it means

editAsset rejects GIF files: when asset.originalPath ends with '.gif' (case-insensitive), it throws BadRequestException('Editing GIF images is not supported'). Animated GIFs cannot be safely cropped/rotated via the edit pipeline, so the operation is blocked.

Solutions

  1. Check the asset's originalPath/originalFileName for a .gif extension before offering or submitting edits
  2. Skip GIFs in bulk edit flows with a user-visible reason
  3. Convert the GIF to a static image (PNG/JPEG) and re-upload if a still edit is required
  4. Handle the 400 'Editing GIF images is not supported' response gracefully in edit tooling

Example fix

// before
await applyEdits(gifAssetId, edits);
// after
if (asset.originalPath.toLowerCase().endsWith('.gif')) return skip('gif');
await applyEdits(gifAssetId, edits);
Defensive patterns

Strategy: validation

Validate before calling

if (asset.originalPath?.toLowerCase().endsWith('.gif')) throw new Error(`Asset ${asset.id} is a GIF; editing not supported`);

Type guard

const isGif = (a: { originalPath?: string | null }) => !!a.originalPath && a.originalPath.toLowerCase().endsWith('.gif');

Try / catch

try { await api.applyEdits(id, edits); } catch (e) { if (String(e?.response?.data?.message).includes('GIF')) { markUnsupported(id, 'gif'); return; } throw e; }

Prevention

When it happens

Trigger: Submitting image edits for an asset whose originalPath has a .gif extension, e.g. a cropped/rotated GIF imported into the library.

Common situations: Editing images downloaded from the web that turn out to be GIFs; bulk edit scripts over a library containing memes/animated GIFs; upload pipelines that accept GIFs but later apply edit jobs to them.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15). Data as JSON: /api/errors/b3e2b3e6ba428af5. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/asset.service.ts:553

    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 e55ac299a4)