{"record":{"id":"e6bd553925d74cb9","repo":"immich-app/immich","slug":"editing-panorama-images-is-not-supported","errorCode":null,"errorMessage":"Editing panorama images is not supported","messagePattern":"Editing panorama images is not supported","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/asset.service.ts","lineNumber":549,"sourceCode":"\n  async editAsset(auth: AuthDto, id: string, dto: AssetEditsCreateDto): Promise<AssetEditsResponseDto> {\n    await this.requireAccess({ auth, permission: Permission.AssetEditCreate, ids: [id] });\n\n    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[];","sourceCodeStart":531,"sourceCodeEnd":567,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/services/asset.service.ts#L531-L567","documentation":"editAsset blocks panorama images: isPanorama(asset) checks the asset's panorama classification (e.g. 360/Ricoh Theta files) and throws BadRequestException('Editing panorama images is not supported'). Crop/rotate transforms are meaningless or destructive for equirectangular panoramas, so they are rejected.","triggerScenarios":"Submitting crop/rotate/flip edits for a 360-degree panorama asset (typically photos with GPS/EXIF panorama metadata from 360 cameras).","commonSituations":"Bulk edits over a library that includes Ricoh Theta / Insta360 / Google Street View panoramas; clients whose edit UI does not distinguish panoramas; scripts applying rotate to fix orientation across all images.","solutions":["Detect panoramas before editing (isPanorama checks via the asset's flags/metadata — skip assets flagged as panorama)","Filter 360-camera imports (e.g. Ricoh Theta) out of bulk edit operations","Handle the 400 response and mark the asset as non-editable in the client UI","Edit panoramas with dedicated 360 tooling instead of crop/rotate edits"],"exampleFix":"// before\nawait applyEdits(panoId, { crop: cropRect });\n// after\nif (asset.isPanorama) return skip('panorama');\nawait applyEdits(panoId, { crop: cropRect });","handlingStrategy":"validation","validationCode":"if (asset.isPanorama) throw new Error(`Asset ${asset.id} is a panorama; editing not supported`);","typeGuard":"const isPanorama = (a: { isPanorama?: boolean; tags?: string[] }) => a.isPanorama === true || !!a.tags?.includes('panorama');","tryCatchPattern":"try { await api.applyEdits(id, edits); } catch (e) { if (String(e?.response?.data?.message).includes('panorama')) { markNonEditable(id); return; } throw e; }","preventionTips":["Detect 360-camera files at import time and flag them","Filter panoramas out of bulk edit batches","Disable crop/rotate controls for equirectangular images","Handle the 400 panorama response as a permanent skip"],"tags":["asset","edit","panorama","unsupported"],"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"}