{"record":{"id":"b3e2b3e6ba428af5","repo":"immich-app/immich","slug":"editing-gif-images-is-not-supported","errorCode":null,"errorMessage":"Editing GIF images is not supported","messagePattern":"Editing GIF images is not supported","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/asset.service.ts","lineNumber":553,"sourceCode":"    const asset = await this.assetRepository.getForEdit(id);\n    if (!asset) {\n      throw new BadRequestException('Asset not found');\n    }\n\n    if (asset.type !== AssetType.Image) {\n      throw new BadRequestException('Only images can be edited');\n    }\n\n    if (asset.livePhotoVideoId) {\n      throw new BadRequestException('Editing live photos is not supported');\n    }\n\n    if (isPanorama(asset)) {\n      throw new BadRequestException('Editing panorama images is not supported');\n    }\n\n    if (asset.originalPath?.toLowerCase().endsWith('.gif')) {\n      throw new BadRequestException('Editing GIF images is not supported');\n    }\n\n    if (asset.originalPath?.toLowerCase().endsWith('.svg')) {\n      throw new BadRequestException('Editing SVG images is not supported');\n    }\n\n    // check that crop parameters will not go out of bounds\n    const { width: assetWidth, height: assetHeight } = getDimensions(asset);\n\n    if (!assetWidth || !assetHeight) {\n      throw new BadRequestException('Asset dimensions are not available for editing');\n    }\n\n    const edits = dto.edits as AssetEditActionItem[];\n    const crop = edits.find((e) => e.action === AssetEditAction.Crop);\n    if (crop) {\n      if (edits[0].action !== AssetEditAction.Crop) {\n        throw new BadRequestException('Crop action must be the first edit action');","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/services/asset.service.ts#L535-L571","documentation":"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.","triggerScenarios":"Submitting image edits for an asset whose originalPath has a .gif extension, e.g. a cropped/rotated GIF imported into the library.","commonSituations":"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.","solutions":["Check the asset's originalPath/originalFileName for a .gif extension before offering or submitting edits","Skip GIFs in bulk edit flows with a user-visible reason","Convert the GIF to a static image (PNG/JPEG) and re-upload if a still edit is required","Handle the 400 'Editing GIF images is not supported' response gracefully in edit tooling"],"exampleFix":"// before\nawait applyEdits(gifAssetId, edits);\n// after\nif (asset.originalPath.toLowerCase().endsWith('.gif')) return skip('gif');\nawait applyEdits(gifAssetId, edits);","handlingStrategy":"validation","validationCode":"if (asset.originalPath?.toLowerCase().endsWith('.gif')) throw new Error(`Asset ${asset.id} is a GIF; editing not supported`);","typeGuard":"const isGif = (a: { originalPath?: string | null }) => !!a.originalPath && a.originalPath.toLowerCase().endsWith('.gif');","tryCatchPattern":"try { await api.applyEdits(id, edits); } catch (e) { if (String(e?.response?.data?.message).includes('GIF')) { markUnsupported(id, 'gif'); return; } throw e; }","preventionTips":["Check originalFileName/originalPath extension before offering edits","Exclude .gif assets from bulk edit pipelines","Convert GIFs to raster stills when a static edit is needed","Remember case-insensitive matching (.GIF too)"],"tags":["asset","edit","gif","unsupported-format"],"backgroundTag":"unsupported-operation","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}