{"record":{"id":"bbf784d80e112b6a","repo":"immich-app/immich","slug":"editing-svg-images-is-not-supported","errorCode":null,"errorMessage":"Editing SVG images is not supported","messagePattern":"Editing SVG images is not supported","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"server/src/services/asset.service.ts","lineNumber":552,"sourceCode":"\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');\n      }\n\n      // check that crop parameters will not go out of bounds\n      const { width: assetWidth, height: assetHeight } = getDimensions(asset);","sourceCodeStart":534,"sourceCodeEnd":570,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/asset.service.ts#L534-L570","documentation":"Thrown by editAsset when asset.originalPath ends with '.svg' (case-insensitive). SVGs are vector graphics, not raster pixel data, so crop/rotate/mirror pixel operations do not apply; the editor rejects them with 400 BadRequest.","triggerScenarios":"PUT /assets/{id}/edits on an asset whose stored originalPath has a .svg extension.","commonSituations":"SVG icons/illustrations imported as assets; client does not filter vector formats before enabling editing.","solutions":["Disable the editor for assets whose path/filename ends in .svg (case-insensitive).","Rasterize the SVG to PNG before editing if pixel transforms are genuinely needed."],"exampleFix":"// before\nconst editable = asset.type === 'IMAGE';\n\n// after\nconst path = (asset.originalPath ?? asset.originalFileName ?? '').toLowerCase();\nconst editable = asset.type === 'IMAGE' && !path.endsWith('.svg');","handlingStrategy":"validation","validationCode":"const path = (asset.originalPath ?? asset.originalFileName ?? '').toLowerCase();\nif (path.endsWith('.svg')) {\n  throw new Error('SVG assets cannot be edited.');\n}\nawait api.put(`/assets/${asset.id}/edits`, { edits });","typeGuard":"const isSvg = (a: { originalPath?: string; originalFileName?: string }): boolean =>\n  (a?.originalPath ?? a?.originalFileName ?? '').toLowerCase().endsWith('.svg');","tryCatchPattern":null,"preventionTips":["Lowercase the path before comparing (server does too).","Hide the editor for vector (.svg) assets.","Rasterize SVGs to PNG first if editing is required."],"tags":["asset","edit","svg","vector","validation","image"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}