immich-app/immich · error · BadRequestException

Only images can be edited

Error message

Only images can be edited

What it means

editAsset only supports editing images; after confirming the asset exists it checks asset.type !== AssetType.Image and throws BadRequestException('Only images can be edited'). Videos and other non-image asset types are rejected by design.

Solutions

  1. Filter assets to type === 'IMAGE' (AssetType.Image) before submitting edits
  2. Skip videos in bulk edit flows with a clear user-facing skip reason
  3. For videos, use video-specific tooling instead of the image edit API
  4. Check the asset's type field from GET /api/assets/:id before editing

Example fix

// before
for (const a of selected) await applyEdits(a.id, edits);
// after
for (const a of selected.filter((a) => a.type === 'IMAGE')) await applyEdits(a.id, edits);
Defensive patterns

Strategy: validation

Validate before calling

if (asset.type !== 'IMAGE') throw new Error(`Asset ${asset.id} is ${asset.type}; only IMAGE assets can be edited`);

Type guard

const isEditableImage = (a: { type: string }) => a.type === 'IMAGE';

Try / catch

try { await api.applyEdits(id, edits); } catch (e) { if (String(e?.response?.data?.message) === 'Only images can be edited') { markUnsupported(id); return; } throw e; }

Prevention

When it happens

Trigger: Submitting an edit (crop/rotate/etc.) for an asset whose type is Video, Motion photo video component, or any non-Image AssetType, e.g. PUT edits on a video id.

Common situations: Bulk edit scripts iterating a playlist or album that includes videos; clients applying UI-edited transforms to all assets in a selection without filtering type; misidentifying a motion photo's video part as the editable asset.

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/0b9273745bb0a97e. Report an issue: GitHub.

Appendix: source

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

    await this.requireAccess({ auth, permission: Permission.AssetRead, ids: [id] });
    const edits = await this.assetEditRepository.getAll(id);

    return {
      assetId: id,
      edits,
    };
  }

  async editAsset(auth: AuthDto, id: string, dto: AssetEditsCreateDto): Promise<AssetEditsResponseDto> {
    await this.requireAccess({ auth, permission: Permission.AssetEditCreate, ids: [id] });

    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');
    }

View on GitHub (pinned to e55ac299a4)