immich-app/immich · error · BadRequestException
Editing SVG images is not supported
Error message
Editing SVG images is not supported
What it means
editAsset rejects SVG files: when asset.originalPath ends with '.svg' (case-insensitive), it throws BadRequestException('Editing SVG images is not supported'). Vector assets are outside the raster edit pipeline's supported inputs, so the edit is rejected before crop-bounds checks.
Solutions
- Check originalPath/originalFileName for an .svg extension before submitting edits
- Rasterize the SVG (e.g. to PNG at a target resolution) and upload that if an edit is required
- Exclude SVG assets from edit-enabled UI surfaces
- Catch the 400 and mark the asset as not editable
Example fix
// before
await applyEdits(svgAssetId, { rotate: 90 });
// after
if (asset.originalPath.toLowerCase().endsWith('.svg')) return skip('svg');
await applyEdits(svgAssetId, { rotate: 90 }); Defensive patterns
Strategy: validation
Validate before calling
if (asset.originalPath?.toLowerCase().endsWith('.svg')) throw new Error(`Asset ${asset.id} is an SVG; editing not supported`); Type guard
const isSvg = (a: { originalPath?: string | null }) => !!a.originalPath && a.originalPath.toLowerCase().endsWith('.svg'); Try / catch
try { await api.applyEdits(id, edits); } catch (e) { if (String(e?.response?.data?.message).includes('SVG')) { markUnsupported(id, 'svg'); return; } throw e; } Prevention
- Filter .svg assets out of edit-enabled surfaces
- Rasterize SVGs to PNG/JPEG before uploading if edits are expected
- Check both originalPath and originalFileName extensions
- Treat the 400 SVG response as a permanent skip, not retryable
When it happens
Trigger: Submitting crop/rotate/flip edits for an asset whose originalPath has an .svg extension — SVGs uploaded or synced into the library.
Common situations: Libraries synced from design tool exports or icon folders containing SVGs; bulk edit scripts that treat every IMAGE-type asset as raster; upload flows accepting SVGs without restricting later edits.
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
- Editing GIF images is not supported
- Editing live photos is not supported
- Editing panorama images is not supported
- Only images can be edited
- Asset not found
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/bbf784d80e112b6a.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/asset.service.ts:557
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');
}
// check that crop parameters will not go out of bounds
const { width: assetWidth, height: assetHeight } = getDimensions(asset);View on GitHub (pinned to e55ac299a4)