Live Photo Video and Sidecar getting deleted when renaming external library folders #6011

Open
opened 2026-02-20 04:07:19 -05:00 by deekerman · 12 comments
Owner

Originally created by @pantra64 on GitHub (Jul 20, 2025).

I have searched the existing issues, both open and closed, to make sure this is not a duplicate report.

  • Yes

The bug

Renaming or moving folders in external libraries leads to deletion and loss of Live Photo .mov and Sidecar .xmp.

This is especially dangerous and sneaky when using the immich-folder-album-creator script with sync 2 mode: When running the script after reorganizing your external library, "offline" assets will get auto-removed and you'll wake up to all your mov- and sidecar files having been deleted.

The OS that Immich Server is running on

Synology DSM 7.2.2-72806 Update 3

Version of Immich Server

v.1.135.3

Version of Immich Mobile App

v.1.135.3

Platform with the issue

  • Server
  • Web
  • Mobile

Your docker-compose.yml content

name: immich

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    # user: "1027:100"
    # extends:
    #   file: hwaccel.transcoding.yml
    #   service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding
    volumes:
      # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - /etc/localtime:/etc/localtime:ro
      - ${EXTERNAL_PATH}:/usr/src/app/external
    env_file:
      - .env
    ports:
      - '2283:2283'
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false

  immich-machine-learning:
    container_name: immich_machine_learning
    # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.
    # Example tag: ${IMMICH_VERSION:-release}-cuda
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
    # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration
    #   file: hwaccel.ml.yml
    #   service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    restart: always
    healthcheck:
      disable: false

  redis:
    container_name: immich_redis
    image: docker.io/valkey/valkey:8-bookworm@sha256:ff21bc0f8194dc9c105b769aeabf9585fea6a8ed649c0781caeac5cb3c247884
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0@sha256:fa4f6e0971f454cd95fec5a9aaed2ed93d8f46725cc6bc61e0698e97dba96da1
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
      # Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs
      # DB_STORAGE_TYPE: 'HDD'
    volumes:
      # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    restart: always

volumes:
  model-cache:

Your .env content

EXTERNAL_PATH=/volume1/homes/pantra/Photos
UPLOAD_LOCATION=./library
DB_DATA_LOCATION=./postgres
list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
TZ=Europe/Berlin
IMMICH_VERSION=release
DB_PASSWORD=postgres
DB_USERNAME=postgres
DB_DATABASE_NAME=immich

Reproduction steps

  1. Have your external library mounted as writeable, not read only (:ro)
  2. place image.heic, image.mov and image.xmp in a folder "test" inside your external library
  3. rename folder to test_renamed
  4. rescan external library in immich until the asset shows up in trash as offline
  5. delete "offline" item from trash inside immich
  6. observe that test.mov and test.xmp get deleted from folder test_renamed, curiously NOT the image.heic though

Relevant log output


Additional information

No response

Originally created by @pantra64 on GitHub (Jul 20, 2025). ### I have searched the existing issues, both open and closed, to make sure this is not a duplicate report. - [x] Yes ### The bug Renaming or moving folders in external libraries leads to deletion and loss of Live Photo .mov and Sidecar .xmp. **This is especially dangerous and sneaky when using the immich-folder-album-creator script with sync 2 mode**: When running the script after reorganizing your external library, "offline" assets will get auto-removed and you'll wake up to all your mov- and sidecar files having been deleted. ### The OS that Immich Server is running on Synology DSM 7.2.2-72806 Update 3 ### Version of Immich Server v.1.135.3 ### Version of Immich Mobile App v.1.135.3 ### Platform with the issue - [x] Server - [x] Web - [ ] Mobile ### Your docker-compose.yml content ```YAML name: immich services: immich-server: container_name: immich_server image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} # user: "1027:100" # extends: # file: hwaccel.transcoding.yml # service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding volumes: # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file - ${UPLOAD_LOCATION}:/usr/src/app/upload - /etc/localtime:/etc/localtime:ro - ${EXTERNAL_PATH}:/usr/src/app/external env_file: - .env ports: - '2283:2283' depends_on: - redis - database restart: always healthcheck: disable: false immich-machine-learning: container_name: immich_machine_learning # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag. # Example tag: ${IMMICH_VERSION:-release}-cuda image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration # file: hwaccel.ml.yml # service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable volumes: - model-cache:/cache env_file: - .env restart: always healthcheck: disable: false redis: container_name: immich_redis image: docker.io/valkey/valkey:8-bookworm@sha256:ff21bc0f8194dc9c105b769aeabf9585fea6a8ed649c0781caeac5cb3c247884 healthcheck: test: redis-cli ping || exit 1 restart: always database: container_name: immich_postgres image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0@sha256:fa4f6e0971f454cd95fec5a9aaed2ed93d8f46725cc6bc61e0698e97dba96da1 environment: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_USER: ${DB_USERNAME} POSTGRES_DB: ${DB_DATABASE_NAME} POSTGRES_INITDB_ARGS: '--data-checksums' # Uncomment the DB_STORAGE_TYPE: 'HDD' var if your database isn't stored on SSDs # DB_STORAGE_TYPE: 'HDD' volumes: # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file - ${DB_DATA_LOCATION}:/var/lib/postgresql/data restart: always volumes: model-cache: ``` ### Your .env content ```Shell EXTERNAL_PATH=/volume1/homes/pantra/Photos UPLOAD_LOCATION=./library DB_DATA_LOCATION=./postgres list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List TZ=Europe/Berlin IMMICH_VERSION=release DB_PASSWORD=postgres DB_USERNAME=postgres DB_DATABASE_NAME=immich ``` ### Reproduction steps 1. Have your external library mounted as writeable, not read only (:ro) 2. place image.heic, image.mov and image.xmp in a folder "test" inside your external library 3. rename folder to test_renamed 4. rescan external library in immich until the asset shows up in trash as offline 5. delete "offline" item from trash inside immich 6. observe that test.mov and test.xmp get deleted from folder test_renamed, curiously NOT the image.heic though ### Relevant log output ```shell ``` ### Additional information _No response_
Author
Owner

@skatsubo commented on GitHub (Jul 21, 2025):

I confirm that the issue is reproducible.

For each of the following steps:

  • Step 1. Add live photo to live directory in ext lib and rescan.
  • Step 2. Rename live directory to renamed in ext lib and rescan.
  • Step 3. Delete the offlined live photo from trash.

the report below includes:

  • List of files in ext lib
  • Records from the assets table
  • Server + database logs

TLDR

After renaming the directory and rescan (step 2) image->video refs in assets become cross-linked / entangled between offline and online pairs:

  • original img.heic -> renamed img.mov
  • renamed img.heic -> original img.mov

⚠️ Then Immich removes online MOV, XMP when emptying trash.

Reproducing

Step 1. Add live photo to live directory in ext lib, then rescan.

External library content on disk:

tree /tmp/extvol/media

/tmp/extvol/media
└── live
    ├── img.heic
    ├── img.mov
    └── img.xmp

Live photo discovered upon rescan and image->video is properly linked by livePhotoVideoId:

-[ RECORD 1 ]----+---------------------------------------------------------------------------------------------------------
type             | IMAGE
originalPath     | /tmp/extvol/media/live/img.heic
livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7

-[ RECORD 2 ]----+---------------------------------------------------------------------------------------------------------
id               | 379bd0ae-9f77-4720-8744-b7cfda56fba7
type             | VIDEO
originalPath     | /tmp/extvol/media/live/img.mov

DB assets:

select * from assets order by "originalPath"; (2 assets)
-[ RECORD 1 ]----+---------------------------------------------------------------------------------------------------------
id               | 85e0945d-3452-4cef-bcc0-1f1b1590a47d
deviceAssetId    | img.heic
ownerId          | 00f8b213-f731-42ef-9bf7-344756c9b437
deviceId         | Library Import
type             | IMAGE
originalPath     | /tmp/extvol/media/live/img.heic
fileCreatedAt    | 2019-12-13 01:47:22.128+00
fileModifiedAt   | 2025-07-21 20:51:41.745+00
isFavorite       | f
duration         | 
encodedVideoPath | 
checksum         | \x1d99d6721aad64a71e1567eb8be761d7c4a3b10d
livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7
updatedAt        | 2025-07-21 20:51:50.84462+00
createdAt        | 2025-07-21 20:51:49.819066+00
originalFileName | img.heic
sidecarPath      | /tmp/extvol/media/live/img.xmp
thumbhash        | \x94f50d1d805676788987788089b88778c1a5ff797d
isOffline        | f
libraryId        | 2e07fb58-bc83-418b-912b-c67836162a80
isExternal       | t
deletedAt        | 
localDateTime    | 2019-12-12 20:47:22.128+00
stackId          | 
duplicateId      | 
status           | active
updateId         | 01982ec1-d1bc-71e5-9fe1-4abed12ce26e
visibility       | timeline
-[ RECORD 2 ]----+---------------------------------------------------------------------------------------------------------
id               | 379bd0ae-9f77-4720-8744-b7cfda56fba7
deviceAssetId    | img.mov
ownerId          | 00f8b213-f731-42ef-9bf7-344756c9b437
deviceId         | Library Import
type             | VIDEO
originalPath     | /tmp/extvol/media/live/img.mov
fileCreatedAt    | 2019-12-13 01:47:21+00
fileModifiedAt   | 2025-07-21 20:51:41.747+00
isFavorite       | f
duration         | 00:00:02.153
encodedVideoPath | upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/37/9b/379bd0ae-9f77-4720-8744-b7cfda56fba7.mp4
checksum         | \x1ddd617b09f39d47d2b00d2035fa49fd3ec5ff24
livePhotoVideoId | 
updatedAt        | 2025-07-21 20:51:50.549645+00
createdAt        | 2025-07-21 20:51:49.819066+00
originalFileName | img.mov
sidecarPath      | /tmp/extvol/media/live/img.xmp
thumbhash        | \x58f50d1d805676788977788089b88778c0a5fe7a6e
isOffline        | f
libraryId        | 2e07fb58-bc83-418b-912b-c67836162a80
isExternal       | t
deletedAt        | 
localDateTime    | 2019-12-12 20:47:21+00
stackId          | 
duplicateId      | 
status           | active
updateId         | 01982ec1-d095-7daf-b7b6-c22944170bd9
visibility       | hidden

Step 2. Rename live directory to renamed in ext lib, then rescan.

External library content on disk:

tree /tmp/extvol/media

/tmp/extvol/media
└── renamed
    ├── img.heic
    ├── img.mov
    └── img.xmp

Assets upon rescan:

  • Old live photo is offlined
  • New live photo discovered
  • Image->video are cross-linked / mixed up (see livePhotoVideoId) between offline and online pairs: live/img.heic -> renamed/img.mov, renamed/img.heic -> live/img.mov. Which explains the outcome of emptying trash.
-[ RECORD 1 ]----+---------------------------------------------------------------------------------------------------------
type             | IMAGE
originalPath     | /tmp/extvol/media/live/img.heic
livePhotoVideoId | ce124416-1b27-4195-a0c7-0c291d9f9bf2
sidecarPath      | /tmp/extvol/media/live/img.xmp
isOffline        | t
-[ RECORD 2 ]----+---------------------------------------------------------------------------------------------------------
id               | 379bd0ae-9f77-4720-8744-b7cfda56fba7
type             | VIDEO
originalPath     | /tmp/extvol/media/live/img.mov
sidecarPath      | /tmp/extvol/media/live/img.xmp
isOffline        | t

-[ RECORD 3 ]----+---------------------------------------------------------------------------------------------------------
type             | IMAGE
originalPath     | /tmp/extvol/media/renamed/img.heic
livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7
sidecarPath      | /tmp/extvol/media/renamed/img.xmp
isOffline        | f
-[ RECORD 4 ]----+---------------------------------------------------------------------------------------------------------
id               | ce124416-1b27-4195-a0c7-0c291d9f9bf2
type             | VIDEO
originalPath     | /tmp/extvol/media/renamed/img.mov
sidecarPath      | /tmp/extvol/media/renamed/img.xmp
isOffline        | f

DB assets:

select * from assets order by "originalPath"; (4 assets)
-[ RECORD 1 ]----+---------------------------------------------------------------------------------------------------------
id               | 85e0945d-3452-4cef-bcc0-1f1b1590a47d
deviceAssetId    | img.heic
ownerId          | 00f8b213-f731-42ef-9bf7-344756c9b437
deviceId         | Library Import
type             | IMAGE
originalPath     | /tmp/extvol/media/live/img.heic
fileCreatedAt    | 2019-12-13 01:47:22.128+00
fileModifiedAt   | 2025-07-21 20:51:41.745+00
isFavorite       | f
duration         | 
encodedVideoPath | 
checksum         | \x1d99d6721aad64a71e1567eb8be761d7c4a3b10d
livePhotoVideoId | ce124416-1b27-4195-a0c7-0c291d9f9bf2
updatedAt        | 2025-07-21 21:00:14.918575+00
createdAt        | 2025-07-21 20:51:49.819066+00
originalFileName | img.heic
sidecarPath      | /tmp/extvol/media/live/img.xmp
thumbhash        | \x94f50d1d805676788987788089b88778c1a5ff797d
isOffline        | t
libraryId        | 2e07fb58-bc83-418b-912b-c67836162a80
isExternal       | t
deletedAt        | 2025-07-21 21:00:14.554+00
localDateTime    | 2019-12-12 20:47:22.128+00
stackId          | 
duplicateId      | 
status           | active
updateId         | 01982ec9-82c6-7f2b-854c-90119d52ed0e
visibility       | timeline
-[ RECORD 2 ]----+---------------------------------------------------------------------------------------------------------
id               | 379bd0ae-9f77-4720-8744-b7cfda56fba7
deviceAssetId    | img.mov
ownerId          | 00f8b213-f731-42ef-9bf7-344756c9b437
deviceId         | Library Import
type             | VIDEO
originalPath     | /tmp/extvol/media/live/img.mov
fileCreatedAt    | 2019-12-13 01:47:21+00
fileModifiedAt   | 2025-07-21 20:51:41.747+00
isFavorite       | f
duration         | 00:00:02.153
encodedVideoPath | upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/37/9b/379bd0ae-9f77-4720-8744-b7cfda56fba7.mp4
checksum         | \x1ddd617b09f39d47d2b00d2035fa49fd3ec5ff24
livePhotoVideoId | 
updatedAt        | 2025-07-21 21:00:14.824562+00
createdAt        | 2025-07-21 20:51:49.819066+00
originalFileName | img.mov
sidecarPath      | /tmp/extvol/media/live/img.xmp
thumbhash        | \x58f50d1d805676788977788089b88778c0a5fe7a6e
isOffline        | t
libraryId        | 2e07fb58-bc83-418b-912b-c67836162a80
isExternal       | t
deletedAt        | 2025-07-21 21:00:14.554+00
localDateTime    | 2019-12-12 20:47:21+00
stackId          | 
duplicateId      | 
status           | active
updateId         | 01982ec9-8268-74ed-8c5f-d7afa1f42018
visibility       | hidden
-[ RECORD 3 ]----+---------------------------------------------------------------------------------------------------------
id               | 349bbc25-66cd-481b-81b7-ee4ed100d63b
deviceAssetId    | img.heic
ownerId          | 00f8b213-f731-42ef-9bf7-344756c9b437
deviceId         | Library Import
type             | IMAGE
originalPath     | /tmp/extvol/media/renamed/img.heic
fileCreatedAt    | 2019-12-13 01:47:22.128+00
fileModifiedAt   | 2025-07-21 20:51:41.745+00
isFavorite       | f
duration         | 
encodedVideoPath | 
checksum         | \xdb2e9437777aeb0d0d01183dec916bbfa2506e70
livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7
updatedAt        | 2025-07-21 21:00:14.824671+00
createdAt        | 2025-07-21 21:00:14.557112+00
originalFileName | img.heic
sidecarPath      | /tmp/extvol/media/renamed/img.xmp
thumbhash        | 
isOffline        | f
libraryId        | 2e07fb58-bc83-418b-912b-c67836162a80
isExternal       | t
deletedAt        | 
localDateTime    | 2019-12-12 20:47:22.128+00
stackId          | 
duplicateId      | 
status           | active
updateId         | 01982ec9-8268-7e20-8fe5-efa195ffb549
visibility       | timeline
-[ RECORD 4 ]----+---------------------------------------------------------------------------------------------------------
id               | ce124416-1b27-4195-a0c7-0c291d9f9bf2
deviceAssetId    | img.mov
ownerId          | 00f8b213-f731-42ef-9bf7-344756c9b437
deviceId         | Library Import
type             | VIDEO
originalPath     | /tmp/extvol/media/renamed/img.mov
fileCreatedAt    | 2019-12-13 01:47:21+00
fileModifiedAt   | 2025-07-21 20:51:41.747+00
isFavorite       | f
duration         | 00:00:02.153
encodedVideoPath | upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/ce/12/ce124416-1b27-4195-a0c7-0c291d9f9bf2.mp4
checksum         | \x9a0f357f0f1d9f99b3b1475186d869315486e473
livePhotoVideoId | 
updatedAt        | 2025-07-21 21:00:15.144269+00
createdAt        | 2025-07-21 21:00:14.557112+00
originalFileName | img.mov
sidecarPath      | /tmp/extvol/media/renamed/img.xmp
thumbhash        | 
isOffline        | f
libraryId        | 2e07fb58-bc83-418b-912b-c67836162a80
isExternal       | t
deletedAt        | 
localDateTime    | 2019-12-12 20:47:21+00
stackId          | 
duplicateId      | 
status           | active
updateId         | 01982ec9-83a8-7608-bfa6-6f06677e0719
visibility       | hidden

Logs:

Rescan log after renaming `live -> renamed` (server: verbose; database: all queries)
immich_server    | [Nest] 16  - 07/21/2025, 9:00:14 PM   DEBUG [Api:JobService~d7msitzt] Handling command: queue=library,command=start,force=undefined
immich_postgres  | 2025-07-21 21:00:14.540 UTC [45] LOG:  execute <unnamed>: select "sessions"."id", "sessions"."updatedAt", "sessions"."pinExpiresAt", (select to_json(obj) from (select "users"."id", "users"."name", "users"."email", "users"."isAdmin", "users"."quotaUsageInBytes", "users"."quotaSizeInBytes" from "users" where "users"."id" = "sessions"."userId" and "users"."deletedAt" is null) as obj) as "user" from "sessions" where "sessions"."token" = $1 and ("sessions"."expiresAt" is null or "sessions"."expiresAt" > $2)
immich_postgres  | 2025-07-21 21:00:14.540 UTC [45] DETAIL:  parameters: $1 = '03g4IgxWwa/4tUj0kqm/g7M+eS5yQoLoXydt3QjGCFE=', $2 = '2025-07-21 21:00:14.539+00'
immich_server    | [Nest] 16  - 07/21/2025, 9:00:14 PM   DEBUG [Api:LoggingInterceptor~d7msitzt] PUT /api/jobs/library 200 1.83ms ::ffff:192.168.65.1
immich_server    | [Nest] 16  - 07/21/2025, 9:00:14 PM VERBOSE [Api:LoggingInterceptor~d7msitzt] {"command":"start"}
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] Initiating scan of all external libraries...
immich_postgres  | 2025-07-21 21:00:14.543 UTC [52] LOG:  statement: select "libraries".* from "libraries" order by "createdAt" asc
immich_postgres  | 2025-07-21 21:00:14.543 UTC [64] LOG:  statement: select "libraries".* from "libraries" where "libraries"."deletedAt" is not null order by "createdAt" asc
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] Checking for any libraries pending deletion...
immich_postgres  | 2025-07-21 21:00:14.545 UTC [63] LOG:  execute <unnamed>: select "libraries".* from "libraries" where "libraries"."id" = $1 and "libraries"."deletedAt" is null
immich_postgres  | 2025-07-21 21:00:14.545 UTC [63] DETAIL:  parameters: $1 = '2e07fb58-bc83-418b-912b-c67836162a80'
immich_postgres  | 2025-07-21 21:00:14.546 UTC [52] LOG:  execute <unnamed>: select count(*) as "count" from "assets" where "libraryId" = $1::uuid
immich_postgres  | 2025-07-21 21:00:14.546 UTC [52] DETAIL:  parameters: $1 = '2e07fb58-bc83-418b-912b-c67836162a80'
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] Checking 2 asset(s) against import paths and exclusion patterns in library 2e07fb58-bc83-418b-912b-c67836162a80...
immich_postgres  | 2025-07-21 21:00:14.546 UTC [65] LOG:  execute <unnamed>: select "libraries".* from "libraries" where "libraries"."id" = $1 and "libraries"."deletedAt" is null
immich_postgres  | 2025-07-21 21:00:14.546 UTC [65] DETAIL:  parameters: $1 = '2e07fb58-bc83-418b-912b-c67836162a80'
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM   DEBUG [Microservices:LibraryService] Validating import paths for library 2e07fb58-bc83-418b-912b-c67836162a80...
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] Starting disk crawl of 1 import path(s) for library 2e07fb58-bc83-418b-912b-c67836162a80...
immich_postgres  | 2025-07-21 21:00:14.551 UTC [64] LOG:  execute <unnamed>: update "assets" set "isOffline" = $1, "deletedAt" = $2 where "isOffline" = $3 and "isExternal" = $4 and "libraryId" = $5::uuid and (not "originalPath" like $6 or ("originalPath" like $7 or "originalPath" like $8 or "originalPath" like $9 or "originalPath" like $10))
immich_postgres  | 2025-07-21 21:00:14.551 UTC [64] DETAIL:  parameters: $1 = 't', $2 = '2025-07-21 21:00:14.546+00', $3 = 'f', $4 = 't', $5 = '2e07fb58-bc83-418b-912b-c67836162a80', $6 = '/tmp/extvol/media%', $7 = '%/@eaDir/%', $8 = '%/._%', $9 = '%/#recycle/%', $10 = '%/#snapshot/%'
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] 0 asset(s) out of 2 were offlined due to import paths and/or exclusion pattern(s) in library 2e07fb58-bc83-418b-912b-c67836162a80
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] Scanning library 2e07fb58-bc83-418b-912b-c67836162a80 for assets missing from disk...
immich_postgres  | 2025-07-21 21:00:14.552 UTC [63] LOG:  execute <unnamed>: select "id" from "assets" where "libraryId" = $1
immich_postgres  | 2025-07-21 21:00:14.552 UTC [63] DETAIL:  parameters: $1 = '2e07fb58-bc83-418b-912b-c67836162a80'
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] Queued check of 2 of 2 (100.0 %) existing asset(s) so far in library 2e07fb58-bc83-418b-912b-c67836162a80
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] Finished queuing 2 asset check(s) for library 2e07fb58-bc83-418b-912b-c67836162a80
immich_postgres  | 2025-07-21 21:00:14.554 UTC [52] LOG:  execute <unnamed>: select "assets"."id", "assets"."isOffline", "assets"."libraryId", "assets"."originalPath", "assets"."status", "assets"."fileModifiedAt" from "assets" where "assets"."id" = any($1::uuid[])
immich_postgres  | 2025-07-21 21:00:14.554 UTC [52] DETAIL:  parameters: $1 = '{379bd0ae-9f77-4720-8744-b7cfda56fba7,85e0945d-3452-4cef-bcc0-1f1b1590a47d}'
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM   DEBUG [Microservices:LibraryService] Checking batch of 2 existing asset(s) in library 2e07fb58-bc83-418b-912b-c67836162a80
immich_postgres  | 2025-07-21 21:00:14.554 UTC [65] LOG:  execute <unnamed>: select "path" from unnest(array[$1, $2]::text[]) as "path" where not exists (select "originalPath" from "assets" where "assets"."originalPath" = "path" and "libraryId" = $3::uuid and "isExternal" = $4)
immich_postgres  | 2025-07-21 21:00:14.554 UTC [65] DETAIL:  parameters: $1 = '/tmp/extvol/media/renamed/img.heic', $2 = '/tmp/extvol/media/renamed/img.mov', $3 = '2e07fb58-bc83-418b-912b-c67836162a80', $4 = 't'
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM   DEBUG [Microservices:LibraryService] Asset /tmp/extvol/media/live/img.mov is no longer on disk or is inaccessible because of permissions, marking offline in library 2e07fb58-bc83-418b-912b-c67836162a80
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM   DEBUG [Microservices:LibraryService] Asset /tmp/extvol/media/live/img.heic is no longer on disk or is inaccessible because of permissions, marking offline in library 2e07fb58-bc83-418b-912b-c67836162a80
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] Crawled 2 file(s) so far: 2 of current batch of 2 will be imported to library 2e07fb58-bc83-418b-912b-c67836162a80...
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] Finished disk crawl, 2 file(s) found on disk and queued 2 file(s) for import into 2e07fb58-bc83-418b-912b-c67836162a80
immich_postgres  | 2025-07-21 21:00:14.555 UTC [64] LOG:  execute <unnamed>: update "assets" set "isOffline" = $1, "deletedAt" = $2 where "id" = any($3::uuid[])
immich_postgres  | 2025-07-21 21:00:14.555 UTC [64] DETAIL:  parameters: $1 = 't', $2 = '2025-07-21 21:00:14.554+00', $3 = '{379bd0ae-9f77-4720-8744-b7cfda56fba7,85e0945d-3452-4cef-bcc0-1f1b1590a47d}'
immich_postgres  | 2025-07-21 21:00:14.555 UTC [63] LOG:  execute <unnamed>: update "libraries" set "refreshedAt" = $1 where "libraries"."id" = $2 returning *
immich_postgres  | 2025-07-21 21:00:14.555 UTC [63] DETAIL:  parameters: $1 = '2025-07-21 21:00:14.555+00', $2 = '2e07fb58-bc83-418b-912b-c67836162a80'
immich_postgres  | 2025-07-21 21:00:14.556 UTC [52] LOG:  execute <unnamed>: select "libraries".* from "libraries" where "libraries"."id" = $1 and "libraries"."deletedAt" is null
immich_postgres  | 2025-07-21 21:00:14.556 UTC [52] DETAIL:  parameters: $1 = '2e07fb58-bc83-418b-912b-c67836162a80'
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] Checked existing asset(s): 2 offlined, 0 onlined, 0 updated, 0 unchanged of current batch of 2 (Total progress: 2 of 2, 100.0 %) in library 2e07fb58-bc83-418b-912b-c67836162a80.
immich_postgres  | 2025-07-21 21:00:14.557 UTC [65] LOG:  execute <unnamed>: insert into "assets" ("ownerId", "libraryId", "checksum", "originalPath", "fileCreatedAt", "fileModifiedAt", "localDateTime", "deviceAssetId", "deviceId", "type", "originalFileName", "isExternal", "livePhotoVideoId") values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13), ($14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26) returning *
immich_postgres  | 2025-07-21 21:00:14.557 UTC [65] DETAIL:  parameters: $1 = '00f8b213-f731-42ef-9bf7-344756c9b437', $2 = '2e07fb58-bc83-418b-912b-c67836162a80', $3 = '\xdb2e9437777aeb0d0d01183dec916bbfa2506e70', $4 = '/tmp/extvol/media/renamed/img.heic', $5 = '2025-07-21 20:51:41.745+00', $6 = '2025-07-21 20:51:41.745+00', $7 = '2025-07-21 20:51:41.745+00', $8 = 'img.heic', $9 = 'Library Import', $10 = 'IMAGE', $11 = 'img.heic', $12 = 't', $13 = NULL, $14 = '00f8b213-f731-42ef-9bf7-344756c9b437', $15 = '2e07fb58-bc83-418b-912b-c67836162a80', $16 = '\x9a0f357f0f1d9f99b3b1475186d869315486e473', $17 = '/tmp/extvol/media/renamed/img.mov', $18 = '2025-07-21 20:51:41.747+00', $19 = '2025-07-21 20:51:41.747+00', $20 = '2025-07-21 20:51:41.747+00', $21 = 'img.mov', $22 = 'Library Import', $23 = 'VIDEO', $24 = 'img.mov', $25 = 't', $26 = NULL
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:LibraryService] Imported 2 (2 done so far) file(s) into library 2e07fb58-bc83-418b-912b-c67836162a80
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM   DEBUG [Microservices:LibraryService] Queuing sidecar discovery for 2 asset(s)
immich_postgres  | 2025-07-21 21:00:14.560 UTC [52] LOG:  execute <unnamed>: select "assets".* from "assets" where "assets"."id" = any($1::uuid[])
immich_postgres  | 2025-07-21 21:00:14.560 UTC [52] DETAIL:  parameters: $1 = '{349bbc25-66cd-481b-81b7-ee4ed100d63b}'
immich_postgres  | 2025-07-21 21:00:14.560 UTC [63] LOG:  execute <unnamed>: select "assets".* from "assets" where "assets"."id" = any($1::uuid[])
immich_postgres  | 2025-07-21 21:00:14.560 UTC [63] DETAIL:  parameters: $1 = '{ce124416-1b27-4195-a0c7-0c291d9f9bf2}'
immich_postgres  | 2025-07-21 21:00:14.561 UTC [64] LOG:  execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "sidecarPath" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId"
immich_postgres  | 2025-07-21 21:00:14.561 UTC [64] DETAIL:  parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b', $2 = '/tmp/extvol/media/renamed/img.xmp', $3 = '349bbc25-66cd-481b-81b7-ee4ed100d63b'
immich_postgres  | 2025-07-21 21:00:14.561 UTC [65] LOG:  execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "sidecarPath" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId"
immich_postgres  | 2025-07-21 21:00:14.561 UTC [65] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = '/tmp/extvol/media/renamed/img.xmp', $3 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_postgres  | 2025-07-21 21:00:14.563 UTC [52] LOG:  execute <unnamed>: select "assets"."id", "assets"."checksum", "assets"."deviceAssetId", "assets"."deviceId", "assets"."fileCreatedAt", "assets"."fileModifiedAt", "assets"."isExternal", "assets"."visibility", "assets"."libraryId", "assets"."livePhotoVideoId", "assets"."localDateTime", "assets"."originalFileName", "assets"."originalPath", "assets"."ownerId", "assets"."sidecarPath", "assets"."type", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".* from "asset_faces" where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" where "assets"."id" = $1
immich_postgres  | 2025-07-21 21:00:14.563 UTC [52] DETAIL:  parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b'
immich_postgres  | 2025-07-21 21:00:14.563 UTC [63] LOG:  execute <unnamed>: select "assets"."id", "assets"."checksum", "assets"."deviceAssetId", "assets"."deviceId", "assets"."fileCreatedAt", "assets"."fileModifiedAt", "assets"."isExternal", "assets"."visibility", "assets"."libraryId", "assets"."livePhotoVideoId", "assets"."localDateTime", "assets"."originalFileName", "assets"."originalPath", "assets"."ownerId", "assets"."sidecarPath", "assets"."type", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".* from "asset_faces" where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" where "assets"."id" = $1
immich_postgres  | 2025-07-21 21:00:14.563 UTC [63] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_server    | <exif details omitted>
immich_postgres  | 2025-07-21 21:00:14.820 UTC [63] LOG:  statement: begin
immich_postgres  | 2025-07-21 21:00:14.821 UTC [63] LOG:  execute <unnamed>: delete from "tag_asset" where "assetsId" = $1
immich_postgres  | 2025-07-21 21:00:14.821 UTC [63] DETAIL:  parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b'
immich_postgres  | 2025-07-21 21:00:14.821 UTC [52] LOG:  execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "duration" = $2, "localDateTime" = $3, "fileCreatedAt" = $4, "fileModifiedAt" = $5 where "id" = $6::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId"
immich_postgres  | 2025-07-21 21:00:14.821 UTC [52] DETAIL:  parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b', $2 = NULL, $3 = '2019-12-12 20:47:22.128+00', $4 = '2019-12-13 01:47:22.128+00', $5 = '2025-07-21 20:51:41.745+00', $6 = '349bbc25-66cd-481b-81b7-ee4ed100d63b'
immich_postgres  | 2025-07-21 21:00:14.821 UTC [63] LOG:  statement: commit
immich_postgres  | 2025-07-21 21:00:14.823 UTC [64] LOG:  execute <unnamed>: select "assets"."id", "assets"."ownerId" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "id" != $1::uuid and "ownerId" = $2::uuid and "type" = $3 and "exif"."livePhotoCID" = $4 limit $5
immich_postgres  | 2025-07-21 21:00:14.823 UTC [64] DETAIL:  parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b', $2 = '00f8b213-f731-42ef-9bf7-344756c9b437', $3 = 'VIDEO', $4 = 'CA20385D-6106-49C9-ACF5-2F8098F4B390', $5 = '1'
immich_postgres  | 2025-07-21 21:00:14.824 UTC [52] LOG:  execute <unnamed>: delete from "albums_assets_assets" where "albums_assets_assets"."assetsId" in ($1)
immich_postgres  | 2025-07-21 21:00:14.824 UTC [52] DETAIL:  parameters: $1 = '379bd0ae-9f77-4720-8744-b7cfda56fba7'
immich_postgres  | 2025-07-21 21:00:14.824 UTC [65] LOG:  execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "visibility" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId"
immich_postgres  | 2025-07-21 21:00:14.824 UTC [65] DETAIL:  parameters: $1 = '379bd0ae-9f77-4720-8744-b7cfda56fba7', $2 = 'hidden', $3 = '379bd0ae-9f77-4720-8744-b7cfda56fba7'
immich_postgres  | 2025-07-21 21:00:14.824 UTC [63] LOG:  execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "livePhotoVideoId" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId"
immich_postgres  | 2025-07-21 21:00:14.824 UTC [63] DETAIL:  parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b', $2 = '379bd0ae-9f77-4720-8744-b7cfda56fba7', $3 = '349bbc25-66cd-481b-81b7-ee4ed100d63b'
immich_postgres  | 2025-07-21 21:00:14.825 UTC [64] LOG:  execute <unnamed>: insert into "asset_job_status" ("assetId", "metadataExtractedAt") values ($1::uuid, $2) on conflict ("assetId") do update set "metadataExtractedAt" = "excluded"."metadataExtractedAt"
immich_postgres  | 2025-07-21 21:00:14.825 UTC [64] DETAIL:  parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b', $2 = '2025-07-21 21:00:14.825+00'
immich_postgres  | 2025-07-21 21:00:14.827 UTC [52] LOG:  execute <unnamed>: select "assets"."id", "assets"."ownerId", "assets"."type", "assets"."checksum", "assets"."originalPath", "assets"."isExternal", "assets"."sidecarPath", "assets"."originalFileName", "assets"."livePhotoVideoId", "assets"."fileCreatedAt", "exif"."timeZone", "exif"."fileSizeInByte" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "assets"."deletedAt" is null and "assets"."id" = $1
immich_postgres  | 2025-07-21 21:00:14.827 UTC [52] DETAIL:  parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b'
immich_postgres  | 2025-07-21 21:00:14.828 UTC [65] LOG:  execute <unnamed>: select "id", "name", "email", "avatarColor", "profileImagePath", "profileChangedAt", "createdAt", "updatedAt", "deletedAt", "isAdmin", "status", "oauthId", "profileImagePath", "shouldChangePassword", "storageLabel", "quotaSizeInBytes", "quotaUsageInBytes", (select coalesce(json_agg(agg), '[]') from (select "user_metadata"."key", "user_metadata"."value" from "user_metadata" where "users"."id" = "user_metadata"."userId") as agg) as "metadata" from "users" where "users"."id" = $1 and "users"."deletedAt" is null
immich_postgres  | 2025-07-21 21:00:14.828 UTC [65] DETAIL:  parameters: $1 = '00f8b213-f731-42ef-9bf7-344756c9b437'
immich_postgres  | 2025-07-21 21:00:14.828 UTC [63] LOG:  execute <unnamed>: select "assets"."id", "assets"."ownerId", "assets"."type", "assets"."checksum", "assets"."originalPath", "assets"."isExternal", "assets"."sidecarPath", "assets"."originalFileName", "assets"."livePhotoVideoId", "assets"."fileCreatedAt", "exif"."timeZone", "exif"."fileSizeInByte" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "assets"."deletedAt" is null and "assets"."id" = $1
immich_postgres  | 2025-07-21 21:00:14.828 UTC [63] DETAIL:  parameters: $1 = '379bd0ae-9f77-4720-8744-b7cfda56fba7'
immich_server    | <exif details omitted>
immich_postgres  | 2025-07-21 21:00:14.913 UTC [63] LOG:  statement: begin
immich_postgres  | 2025-07-21 21:00:14.914 UTC [63] LOG:  execute <unnamed>: delete from "tag_asset" where "assetsId" = $1
immich_postgres  | 2025-07-21 21:00:14.914 UTC [63] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_postgres  | 2025-07-21 21:00:14.914 UTC [65] LOG:  execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "duration" = $2, "localDateTime" = $3, "fileCreatedAt" = $4, "fileModifiedAt" = $5 where "id" = $6::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId"
immich_postgres  | 2025-07-21 21:00:14.914 UTC [65] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = '00:00:02.153', $3 = '2019-12-12 20:47:21+00', $4 = '2019-12-13 01:47:21+00', $5 = '2025-07-21 20:51:41.747+00', $6 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_postgres  | 2025-07-21 21:00:14.915 UTC [63] LOG:  statement: commit
immich_postgres  | 2025-07-21 21:00:14.917 UTC [64] LOG:  execute <unnamed>: select "assets"."id", "assets"."ownerId" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "id" != $1::uuid and "ownerId" = $2::uuid and "type" = $3 and "exif"."livePhotoCID" = $4 limit $5
immich_postgres  | 2025-07-21 21:00:14.917 UTC [64] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = '00f8b213-f731-42ef-9bf7-344756c9b437', $3 = 'IMAGE', $4 = 'CA20385D-6106-49C9-ACF5-2F8098F4B390', $5 = '1'
immich_postgres  | 2025-07-21 21:00:14.918 UTC [52] LOG:  execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "visibility" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId"
immich_postgres  | 2025-07-21 21:00:14.918 UTC [52] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = 'hidden', $3 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_postgres  | 2025-07-21 21:00:14.918 UTC [63] LOG:  execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "livePhotoVideoId" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId"
immich_postgres  | 2025-07-21 21:00:14.918 UTC [63] DETAIL:  parameters: $1 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d', $2 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $3 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d'
immich_postgres  | 2025-07-21 21:00:14.919 UTC [65] LOG:  execute <unnamed>: delete from "albums_assets_assets" where "albums_assets_assets"."assetsId" in ($1)
immich_postgres  | 2025-07-21 21:00:14.919 UTC [65] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_postgres  | 2025-07-21 21:00:14.920 UTC [64] LOG:  execute <unnamed>: insert into "asset_job_status" ("assetId", "metadataExtractedAt") values ($1::uuid, $2) on conflict ("assetId") do update set "metadataExtractedAt" = "excluded"."metadataExtractedAt"
immich_postgres  | 2025-07-21 21:00:14.920 UTC [64] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = '2025-07-21 21:00:14.919+00'
immich_postgres  | 2025-07-21 21:00:14.921 UTC [52] LOG:  execute <unnamed>: select "assets"."id", "assets"."ownerId", "assets"."type", "assets"."checksum", "assets"."originalPath", "assets"."isExternal", "assets"."sidecarPath", "assets"."originalFileName", "assets"."livePhotoVideoId", "assets"."fileCreatedAt", "exif"."timeZone", "exif"."fileSizeInByte" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "assets"."deletedAt" is null and "assets"."id" = $1
immich_postgres  | 2025-07-21 21:00:14.921 UTC [52] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_postgres  | 2025-07-21 21:00:14.922 UTC [65] LOG:  execute <unnamed>: select "id", "name", "email", "avatarColor", "profileImagePath", "profileChangedAt", "createdAt", "updatedAt", "deletedAt", "isAdmin", "status", "oauthId", "profileImagePath", "shouldChangePassword", "storageLabel", "quotaSizeInBytes", "quotaUsageInBytes", (select coalesce(json_agg(agg), '[]') from (select "user_metadata"."key", "user_metadata"."value" from "user_metadata" where "users"."id" = "user_metadata"."userId") as agg) as "metadata" from "users" where "users"."id" = $1 and "users"."deletedAt" is null
immich_postgres  | 2025-07-21 21:00:14.922 UTC [65] DETAIL:  parameters: $1 = '00f8b213-f731-42ef-9bf7-344756c9b437'
immich_postgres  | 2025-07-21 21:00:14.924 UTC [63] LOG:  execute <unnamed>: select "assets"."id", "assets"."visibility", "assets"."originalFileName", "assets"."originalPath", "assets"."ownerId", "assets"."thumbhash", "assets"."type", (select coalesce(json_agg(agg), '[]') from (select "asset_files"."id", "asset_files"."path", "asset_files"."type" from "asset_files" where "asset_files"."assetId" = "assets"."id") as agg) as "files", to_json("exif") as "exifInfo" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "assets"."id" = $1
immich_postgres  | 2025-07-21 21:00:14.924 UTC [63] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM VERBOSE [Microservices:MediaService] Thumbnail generation skipped for asset ce124416-1b27-4195-a0c7-0c291d9f9bf2: not visible
immich_postgres  | 2025-07-21 21:00:14.926 UTC [64] LOG:  execute <unnamed>: select "assets".*, (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces", (select coalesce(json_agg(agg), '[]') from (select "tags"."id", "tags"."value", "tags"."createdAt", "tags"."updatedAt", "tags"."color", "tags"."parentId" from "tags" inner join "tag_asset" on "tags"."id" = "tag_asset"."tagsId" where "assets"."id" = "tag_asset"."assetsId") as agg) as "tags", to_json("exif") as "exifInfo" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" where "assets"."id" = any($1::uuid[])
immich_postgres  | 2025-07-21 21:00:14.926 UTC [64] DETAIL:  parameters: $1 = '{ce124416-1b27-4195-a0c7-0c291d9f9bf2}'
immich_postgres  | 2025-07-21 21:00:14.928 UTC [52] LOG:  execute <unnamed>: select "assets"."id", "assets"."ownerId", "assets"."originalPath", "assets"."encodedVideoPath" from "assets" where "assets"."id" = $1 and "assets"."type" = $2
immich_postgres  | 2025-07-21 21:00:14.928 UTC [52] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = 'VIDEO'
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM     LOG [Microservices:MediaService] Transcoding video ce124416-1b27-4195-a0c7-0c291d9f9bf2 without hardware acceleration
immich_server    | [Nest] 6  - 07/21/2025, 9:00:14 PM   DEBUG [Microservices:MediaRepository] ffmpeg -n 10 /usr/bin/ffmpeg -i /tmp/extvol/media/renamed/img.mov -y -c:v h264 -c:a copy -movflags faststart -fps_mode passthrough -map 0:0 -map_metadata -1 -map 0:1 -v verbose -vf scale=-2:720 -preset ultrafast -crf 23 upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/ce/12/ce124416-1b27-4195-a0c7-0c291d9f9bf2.mp4
immich_server    | [Nest] 6  - 07/21/2025, 9:00:15 PM   DEBUG [Microservices:MediaRepository] Transcoding 100.00% done for output ce124416-1b27-4195-a0c7-0c291d9f9bf2.mp4
immich_server    | [Nest] 6  - 07/21/2025, 9:00:15 PM     LOG [Microservices:MediaService] Successfully encoded ce124416-1b27-4195-a0c7-0c291d9f9bf2
immich_postgres  | 2025-07-21 21:00:15.144 UTC [65] LOG:  execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "encodedVideoPath" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId"
immich_postgres  | 2025-07-21 21:00:15.144 UTC [65] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = 'upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/ce/12/ce124416-1b27-4195-a0c7-0c291d9f9bf2.mp4', $3 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'

Step 3. Delete the offlined live photo from trash.

External library content on disk:

  • Offline HEIC, MOV, XMP were removed
  • Online HEIC is present
  • Online MOV, XMP were removed
tree /tmp/extvol/media

/tmp/extvol/media
└── renamed
    └── img.heic

Assets upon deleting offline live photo from trash:

  • Offline HEIC was removed
  • Offline MOV is present
  • Online HEIC is present
  • Online MOV was removed
  • Image->video is cross-linked / mixed up: renamed/img.heic -> live/img.mov
-[ RECORD 1 ]----+---------------------------------------------------------------------------------------------------------
id               | 379bd0ae-9f77-4720-8744-b7cfda56fba7
type             | VIDEO
originalPath     | /tmp/extvol/media/live/img.mov
isOffline        | t
-[ RECORD 2 ]----+---------------------------------------------------------------------------------------------------------
type             | IMAGE
originalPath     | /tmp/extvol/media/renamed/img.heic
livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7
isOffline        | f

DB assets:

select * from assets order by "originalPath"; (2 assets)
-[ RECORD 1 ]----+---------------------------------------------------------------------------------------------------------
id               | 379bd0ae-9f77-4720-8744-b7cfda56fba7
deviceAssetId    | img.mov
ownerId          | 00f8b213-f731-42ef-9bf7-344756c9b437
deviceId         | Library Import
type             | VIDEO
originalPath     | /tmp/extvol/media/live/img.mov
fileCreatedAt    | 2019-12-13 01:47:21+00
fileModifiedAt   | 2025-07-21 20:51:41.747+00
isFavorite       | f
duration         | 00:00:02.153
encodedVideoPath | upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/37/9b/379bd0ae-9f77-4720-8744-b7cfda56fba7.mp4
checksum         | \x1ddd617b09f39d47d2b00d2035fa49fd3ec5ff24
livePhotoVideoId | 
updatedAt        | 2025-07-21 21:00:14.824562+00
createdAt        | 2025-07-21 20:51:49.819066+00
originalFileName | img.mov
sidecarPath      | /tmp/extvol/media/live/img.xmp
thumbhash        | \x58f50d1d805676788977788089b88778c0a5fe7a6e
isOffline        | t
libraryId        | 2e07fb58-bc83-418b-912b-c67836162a80
isExternal       | t
deletedAt        | 2025-07-21 21:00:14.554+00
localDateTime    | 2019-12-12 20:47:21+00
stackId          | 
duplicateId      | 
status           | active
updateId         | 01982ec9-8268-74ed-8c5f-d7afa1f42018
visibility       | hidden
-[ RECORD 2 ]----+---------------------------------------------------------------------------------------------------------
id               | 349bbc25-66cd-481b-81b7-ee4ed100d63b
deviceAssetId    | img.heic
ownerId          | 00f8b213-f731-42ef-9bf7-344756c9b437
deviceId         | Library Import
type             | IMAGE
originalPath     | /tmp/extvol/media/renamed/img.heic
fileCreatedAt    | 2019-12-13 01:47:22.128+00
fileModifiedAt   | 2025-07-21 20:51:41.745+00
isFavorite       | f
duration         | 
encodedVideoPath | 
checksum         | \xdb2e9437777aeb0d0d01183dec916bbfa2506e70
livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7
updatedAt        | 2025-07-21 21:00:14.824671+00
createdAt        | 2025-07-21 21:00:14.557112+00
originalFileName | img.heic
sidecarPath      | /tmp/extvol/media/renamed/img.xmp
thumbhash        | 
isOffline        | f
libraryId        | 2e07fb58-bc83-418b-912b-c67836162a80
isExternal       | t
deletedAt        | 
localDateTime    | 2019-12-12 20:47:22.128+00
stackId          | 
duplicateId      | 
status           | active
updateId         | 01982ec9-8268-7e20-8fe5-efa195ffb549
visibility       | timeline

Logs:

Log of deleting offlined asset from trash
immich_postgres  | 2025-07-21 21:41:53.372 UTC [45] LOG:  execute <unnamed>: select "sessions"."id", "sessions"."updatedAt", "sessions"."pinExpiresAt", (select to_json(obj) from (select "users"."id", "users"."name", "users"."email", "users"."isAdmin", "users"."quotaUsageInBytes", "users"."quotaSizeInBytes" from "users" where "users"."id" = "sessions"."userId" and "users"."deletedAt" is null) as obj) as "user" from "sessions" where "sessions"."token" = $1 and ("sessions"."expiresAt" is null or "sessions"."expiresAt" > $2)
immich_postgres  | 2025-07-21 21:41:53.372 UTC [45] DETAIL:  parameters: $1 = '03g4IgxWwa/4tUj0kqm/g7M+eS5yQoLoXydt3QjGCFE=', $2 = '2025-07-21 21:41:53.372+00'
immich_postgres  | 2025-07-21 21:41:53.374 UTC [46] LOG:  execute <unnamed>: select "assets"."id" from "assets" where "assets"."id" in ($1) and "assets"."ownerId" = $2 and "assets"."visibility" != $3
immich_postgres  | 2025-07-21 21:41:53.374 UTC [46] DETAIL:  parameters: $1 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d', $2 = '00f8b213-f731-42ef-9bf7-344756c9b437', $3 = 'locked'
immich_postgres  | 2025-07-21 21:41:53.374 UTC [45] LOG:  execute <unnamed>: update "assets" set "deletedAt" = $1, "status" = $2 where "id" = any($3::uuid[])
immich_postgres  | 2025-07-21 21:41:53.374 UTC [45] DETAIL:  parameters: $1 = '2025-07-21 21:41:53.374+00', $2 = 'deleted', $3 = '{85e0945d-3452-4cef-bcc0-1f1b1590a47d}'
immich_server    | [Nest] 16  - 07/21/2025, 9:41:53 PM   DEBUG [Api:LoggingInterceptor~4oldyr8y] DELETE /api/assets 204 8.05ms ::ffff:192.168.65.1
immich_server    | [Nest] 16  - 07/21/2025, 9:41:53 PM VERBOSE [Api:LoggingInterceptor~4oldyr8y] {"ids":["85e0945d-3452-4cef-bcc0-1f1b1590a47d"],"force":true}
immich_postgres  | 2025-07-21 21:41:53.397 UTC [166] LOG:  execute wzjz461vydd1: 
immich_postgres  | 	      select b.oid, b.typarray
immich_postgres  | 	      from pg_catalog.pg_type a
immich_postgres  | 	      left join pg_catalog.pg_type b on b.oid = a.typelem
immich_postgres  | 	      where a.typcategory = 'A'
immich_postgres  | 	      group by b.oid, b.typarray
immich_postgres  | 	      order by b.oid
immich_postgres  | 	    
immich_postgres  | 2025-07-21 21:41:53.403 UTC [166] LOG:  execute <unnamed>: select "id" from "assets" where "status" = $1
immich_postgres  | 2025-07-21 21:41:53.403 UTC [166] DETAIL:  parameters: $1 = 'deleted'
immich_server    | [Nest] 6  - 07/21/2025, 9:41:53 PM   DEBUG [Microservices:TrashService] Queueing 1 asset(s) for deletion from the trash
immich_server    | [Nest] 6  - 07/21/2025, 9:41:53 PM     LOG [Microservices:TrashService] Queued 1 asset(s) for deletion from the trash
immich_postgres  | 2025-07-21 21:41:53.413 UTC [166] LOG:  execute <unnamed>: select "assets"."id", "assets"."visibility", "assets"."libraryId", "assets"."ownerId", "assets"."livePhotoVideoId", "assets"."sidecarPath", "assets"."encodedVideoPath", "assets"."originalPath", to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces", (select coalesce(json_agg(agg), '[]') from (select "asset_files"."id", "asset_files"."path", "asset_files"."type" from "asset_files" where "asset_files"."assetId" = "assets"."id") as agg) as "files", to_json("stacked_assets") as "stack" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" left join "asset_stack" on "asset_stack"."id" = "assets"."stackId" left join lateral (select "asset_stack"."id", "asset_stack"."primaryAssetId", array_agg("stacked") as "assets" from "assets" as "stacked" where "stacked"."deletedAt" is not null and "stacked"."visibility" = $1 and "stacked"."stackId" = "asset_stack"."id" group by "asset_stack"."id") as "stacked_assets" on "asset_stack"."id" is not null where "assets"."id" = $2
immich_postgres  | 2025-07-21 21:41:53.413 UTC [166] DETAIL:  parameters: $1 = 'timeline', $2 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d'
immich_postgres  | 2025-07-21 21:41:53.414 UTC [166] LOG:  execute <unnamed>: delete from "assets" where "id" = $1::uuid
immich_postgres  | 2025-07-21 21:41:53.414 UTC [166] DETAIL:  parameters: $1 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d'
immich_server    | [Nest] 6  - 07/21/2025, 9:41:53 PM   DEBUG [Microservices:StorageTemplateService] Cleaning up move history for asset 85e0945d-3452-4cef-bcc0-1f1b1590a47d
immich_postgres  | 2025-07-21 21:41:53.423 UTC [166] LOG:  execute <unnamed>: delete from "move_history" where "move_history"."pathType" = 'original' and "entityId" = $1
immich_postgres  | 2025-07-21 21:41:53.423 UTC [166] DETAIL:  parameters: $1 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d'
immich_postgres  | 2025-07-21 21:41:53.424 UTC [166] LOG:  execute <unnamed>: select count(*) as "count" from "assets" where "livePhotoVideoId" = $1::uuid
immich_postgres  | 2025-07-21 21:41:53.424 UTC [166] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_postgres  | 2025-07-21 21:41:53.427 UTC [166] LOG:  execute <unnamed>: select "assets"."id", "assets"."visibility", "assets"."libraryId", "assets"."ownerId", "assets"."livePhotoVideoId", "assets"."sidecarPath", "assets"."encodedVideoPath", "assets"."originalPath", to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces", (select coalesce(json_agg(agg), '[]') from (select "asset_files"."id", "asset_files"."path", "asset_files"."type" from "asset_files" where "asset_files"."assetId" = "assets"."id") as agg) as "files", to_json("stacked_assets") as "stack" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" left join "asset_stack" on "asset_stack"."id" = "assets"."stackId" left join lateral (select "asset_stack"."id", "asset_stack"."primaryAssetId", array_agg("stacked") as "assets" from "assets" as "stacked" where "stacked"."deletedAt" is not null and "stacked"."visibility" = $1 and "stacked"."stackId" = "asset_stack"."id" group by "asset_stack"."id") as "stacked_assets" on "asset_stack"."id" is not null where "assets"."id" = $2
immich_postgres  | 2025-07-21 21:41:53.427 UTC [166] DETAIL:  parameters: $1 = 'timeline', $2 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_postgres  | 2025-07-21 21:41:53.428 UTC [166] LOG:  execute <unnamed>: delete from "assets" where "id" = $1::uuid
immich_postgres  | 2025-07-21 21:41:53.428 UTC [166] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_server    | [Nest] 6  - 07/21/2025, 9:41:53 PM   DEBUG [Microservices:StorageTemplateService] Cleaning up move history for asset ce124416-1b27-4195-a0c7-0c291d9f9bf2
immich_postgres  | 2025-07-21 21:41:53.430 UTC [166] LOG:  execute <unnamed>: delete from "move_history" where "move_history"."pathType" = 'original' and "entityId" = $1
immich_postgres  | 2025-07-21 21:41:53.430 UTC [166] DETAIL:  parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2'
immich_server    | [Nest] 6  - 07/21/2025, 9:41:53 PM    WARN [Microservices:StorageRepository] File /tmp/extvol/media/live/img.xmp does not exist.
immich_server    | [Nest] 6  - 07/21/2025, 9:41:53 PM    WARN [Microservices:StorageRepository] File /tmp/extvol/media/live/img.heic does not exist.
immich_server    | [Nest] 6  - 07/21/2025, 9:41:55 PM   DEBUG [Microservices:VersionService] Running version check
immich_postgres  | 2025-07-21 21:41:55.189 UTC [166] LOG:  execute <unnamed>: select "value" from "system_metadata" where "key" = $1
immich_postgres  | 2025-07-21 21:41:55.189 UTC [166] DETAIL:  parameters: $1 = 'version-check-state'
immich_postgres  | 2025-07-21 21:41:55.440 UTC [166] LOG:  execute <unnamed>: insert into "system_metadata" ("key", "value") values ($1, $2) on conflict ("key") do update set "value" = $3
immich_postgres  | 2025-07-21 21:41:55.440 UTC [166] DETAIL:  parameters: $1 = 'version-check-state', $2 = '{"checkedAt": "2025-07-21T21:41:55.438Z", "releaseVersion": "v1.135.3"}', $3 = '{"checkedAt": "2025-07-21T21:41:55.438Z", "releaseVersion": "v1.135.3"}'
immich_server    | [Nest] 16  - 07/21/2025, 9:42:13 PM   DEBUG [Api:LoggingInterceptor~uvj4mufd] GET /api/server/ping 200 0.14ms ::ffff:127.0.0.1
@skatsubo commented on GitHub (Jul 21, 2025): I confirm that the issue is reproducible. For each of the following steps: - Step 1. Add live photo to `live` directory in ext lib and rescan. - Step 2. Rename `live` directory to `renamed` in ext lib and rescan. - Step 3. Delete the offlined live photo from trash. the report below includes: - List of files in ext lib - Records from the `assets` table - Server + database logs ## TLDR After renaming the directory and rescan (step 2) image->video refs in `assets` become cross-linked / entangled between offline and online pairs: - `original img.heic -> renamed img.mov` - `renamed img.heic -> original img.mov` ⚠️ Then Immich removes _online_ MOV, XMP when emptying trash. ## Reproducing ### Step 1. Add live photo to `live` directory in ext lib, then rescan. External library content on disk: ```sh tree /tmp/extvol/media /tmp/extvol/media └── live ├── img.heic ├── img.mov └── img.xmp ``` Live photo discovered upon rescan and image->video is properly linked by `livePhotoVideoId`: ```sql -[ RECORD 1 ]----+--------------------------------------------------------------------------------------------------------- type | IMAGE originalPath | /tmp/extvol/media/live/img.heic livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7 -[ RECORD 2 ]----+--------------------------------------------------------------------------------------------------------- id | 379bd0ae-9f77-4720-8744-b7cfda56fba7 type | VIDEO originalPath | /tmp/extvol/media/live/img.mov ``` DB `assets`: <details> <summary>select * from assets order by "originalPath"; (2 assets)</summary> ```sql -[ RECORD 1 ]----+--------------------------------------------------------------------------------------------------------- id | 85e0945d-3452-4cef-bcc0-1f1b1590a47d deviceAssetId | img.heic ownerId | 00f8b213-f731-42ef-9bf7-344756c9b437 deviceId | Library Import type | IMAGE originalPath | /tmp/extvol/media/live/img.heic fileCreatedAt | 2019-12-13 01:47:22.128+00 fileModifiedAt | 2025-07-21 20:51:41.745+00 isFavorite | f duration | encodedVideoPath | checksum | \x1d99d6721aad64a71e1567eb8be761d7c4a3b10d livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7 updatedAt | 2025-07-21 20:51:50.84462+00 createdAt | 2025-07-21 20:51:49.819066+00 originalFileName | img.heic sidecarPath | /tmp/extvol/media/live/img.xmp thumbhash | \x94f50d1d805676788987788089b88778c1a5ff797d isOffline | f libraryId | 2e07fb58-bc83-418b-912b-c67836162a80 isExternal | t deletedAt | localDateTime | 2019-12-12 20:47:22.128+00 stackId | duplicateId | status | active updateId | 01982ec1-d1bc-71e5-9fe1-4abed12ce26e visibility | timeline -[ RECORD 2 ]----+--------------------------------------------------------------------------------------------------------- id | 379bd0ae-9f77-4720-8744-b7cfda56fba7 deviceAssetId | img.mov ownerId | 00f8b213-f731-42ef-9bf7-344756c9b437 deviceId | Library Import type | VIDEO originalPath | /tmp/extvol/media/live/img.mov fileCreatedAt | 2019-12-13 01:47:21+00 fileModifiedAt | 2025-07-21 20:51:41.747+00 isFavorite | f duration | 00:00:02.153 encodedVideoPath | upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/37/9b/379bd0ae-9f77-4720-8744-b7cfda56fba7.mp4 checksum | \x1ddd617b09f39d47d2b00d2035fa49fd3ec5ff24 livePhotoVideoId | updatedAt | 2025-07-21 20:51:50.549645+00 createdAt | 2025-07-21 20:51:49.819066+00 originalFileName | img.mov sidecarPath | /tmp/extvol/media/live/img.xmp thumbhash | \x58f50d1d805676788977788089b88778c0a5fe7a6e isOffline | f libraryId | 2e07fb58-bc83-418b-912b-c67836162a80 isExternal | t deletedAt | localDateTime | 2019-12-12 20:47:21+00 stackId | duplicateId | status | active updateId | 01982ec1-d095-7daf-b7b6-c22944170bd9 visibility | hidden ``` </details> ### Step 2. Rename `live` directory to `renamed` in ext lib, then rescan. External library content on disk: ```sh tree /tmp/extvol/media /tmp/extvol/media └── renamed ├── img.heic ├── img.mov └── img.xmp ``` Assets upon rescan: - ✅ Old live photo is offlined - ✅ New live photo discovered - ❌ Image->video are cross-linked / mixed up (see `livePhotoVideoId`) between offline and online pairs: `live/img.heic -> renamed/img.mov`, `renamed/img.heic -> live/img.mov`. Which explains the outcome of emptying trash. ```sql -[ RECORD 1 ]----+--------------------------------------------------------------------------------------------------------- type | IMAGE originalPath | /tmp/extvol/media/live/img.heic livePhotoVideoId | ce124416-1b27-4195-a0c7-0c291d9f9bf2 sidecarPath | /tmp/extvol/media/live/img.xmp isOffline | t -[ RECORD 2 ]----+--------------------------------------------------------------------------------------------------------- id | 379bd0ae-9f77-4720-8744-b7cfda56fba7 type | VIDEO originalPath | /tmp/extvol/media/live/img.mov sidecarPath | /tmp/extvol/media/live/img.xmp isOffline | t -[ RECORD 3 ]----+--------------------------------------------------------------------------------------------------------- type | IMAGE originalPath | /tmp/extvol/media/renamed/img.heic livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7 sidecarPath | /tmp/extvol/media/renamed/img.xmp isOffline | f -[ RECORD 4 ]----+--------------------------------------------------------------------------------------------------------- id | ce124416-1b27-4195-a0c7-0c291d9f9bf2 type | VIDEO originalPath | /tmp/extvol/media/renamed/img.mov sidecarPath | /tmp/extvol/media/renamed/img.xmp isOffline | f ``` DB `assets`: <details> <summary>select * from assets order by "originalPath"; (4 assets)</summary> ```sql -[ RECORD 1 ]----+--------------------------------------------------------------------------------------------------------- id | 85e0945d-3452-4cef-bcc0-1f1b1590a47d deviceAssetId | img.heic ownerId | 00f8b213-f731-42ef-9bf7-344756c9b437 deviceId | Library Import type | IMAGE originalPath | /tmp/extvol/media/live/img.heic fileCreatedAt | 2019-12-13 01:47:22.128+00 fileModifiedAt | 2025-07-21 20:51:41.745+00 isFavorite | f duration | encodedVideoPath | checksum | \x1d99d6721aad64a71e1567eb8be761d7c4a3b10d livePhotoVideoId | ce124416-1b27-4195-a0c7-0c291d9f9bf2 updatedAt | 2025-07-21 21:00:14.918575+00 createdAt | 2025-07-21 20:51:49.819066+00 originalFileName | img.heic sidecarPath | /tmp/extvol/media/live/img.xmp thumbhash | \x94f50d1d805676788987788089b88778c1a5ff797d isOffline | t libraryId | 2e07fb58-bc83-418b-912b-c67836162a80 isExternal | t deletedAt | 2025-07-21 21:00:14.554+00 localDateTime | 2019-12-12 20:47:22.128+00 stackId | duplicateId | status | active updateId | 01982ec9-82c6-7f2b-854c-90119d52ed0e visibility | timeline -[ RECORD 2 ]----+--------------------------------------------------------------------------------------------------------- id | 379bd0ae-9f77-4720-8744-b7cfda56fba7 deviceAssetId | img.mov ownerId | 00f8b213-f731-42ef-9bf7-344756c9b437 deviceId | Library Import type | VIDEO originalPath | /tmp/extvol/media/live/img.mov fileCreatedAt | 2019-12-13 01:47:21+00 fileModifiedAt | 2025-07-21 20:51:41.747+00 isFavorite | f duration | 00:00:02.153 encodedVideoPath | upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/37/9b/379bd0ae-9f77-4720-8744-b7cfda56fba7.mp4 checksum | \x1ddd617b09f39d47d2b00d2035fa49fd3ec5ff24 livePhotoVideoId | updatedAt | 2025-07-21 21:00:14.824562+00 createdAt | 2025-07-21 20:51:49.819066+00 originalFileName | img.mov sidecarPath | /tmp/extvol/media/live/img.xmp thumbhash | \x58f50d1d805676788977788089b88778c0a5fe7a6e isOffline | t libraryId | 2e07fb58-bc83-418b-912b-c67836162a80 isExternal | t deletedAt | 2025-07-21 21:00:14.554+00 localDateTime | 2019-12-12 20:47:21+00 stackId | duplicateId | status | active updateId | 01982ec9-8268-74ed-8c5f-d7afa1f42018 visibility | hidden -[ RECORD 3 ]----+--------------------------------------------------------------------------------------------------------- id | 349bbc25-66cd-481b-81b7-ee4ed100d63b deviceAssetId | img.heic ownerId | 00f8b213-f731-42ef-9bf7-344756c9b437 deviceId | Library Import type | IMAGE originalPath | /tmp/extvol/media/renamed/img.heic fileCreatedAt | 2019-12-13 01:47:22.128+00 fileModifiedAt | 2025-07-21 20:51:41.745+00 isFavorite | f duration | encodedVideoPath | checksum | \xdb2e9437777aeb0d0d01183dec916bbfa2506e70 livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7 updatedAt | 2025-07-21 21:00:14.824671+00 createdAt | 2025-07-21 21:00:14.557112+00 originalFileName | img.heic sidecarPath | /tmp/extvol/media/renamed/img.xmp thumbhash | isOffline | f libraryId | 2e07fb58-bc83-418b-912b-c67836162a80 isExternal | t deletedAt | localDateTime | 2019-12-12 20:47:22.128+00 stackId | duplicateId | status | active updateId | 01982ec9-8268-7e20-8fe5-efa195ffb549 visibility | timeline -[ RECORD 4 ]----+--------------------------------------------------------------------------------------------------------- id | ce124416-1b27-4195-a0c7-0c291d9f9bf2 deviceAssetId | img.mov ownerId | 00f8b213-f731-42ef-9bf7-344756c9b437 deviceId | Library Import type | VIDEO originalPath | /tmp/extvol/media/renamed/img.mov fileCreatedAt | 2019-12-13 01:47:21+00 fileModifiedAt | 2025-07-21 20:51:41.747+00 isFavorite | f duration | 00:00:02.153 encodedVideoPath | upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/ce/12/ce124416-1b27-4195-a0c7-0c291d9f9bf2.mp4 checksum | \x9a0f357f0f1d9f99b3b1475186d869315486e473 livePhotoVideoId | updatedAt | 2025-07-21 21:00:15.144269+00 createdAt | 2025-07-21 21:00:14.557112+00 originalFileName | img.mov sidecarPath | /tmp/extvol/media/renamed/img.xmp thumbhash | isOffline | f libraryId | 2e07fb58-bc83-418b-912b-c67836162a80 isExternal | t deletedAt | localDateTime | 2019-12-12 20:47:21+00 stackId | duplicateId | status | active updateId | 01982ec9-83a8-7608-bfa6-6f06677e0719 visibility | hidden ``` </details> Logs: <details> <summary>Rescan log after renaming `live -> renamed` (server: verbose; database: all queries)</summary> ```sql immich_server | [Nest] 16 - 07/21/2025, 9:00:14 PM DEBUG [Api:JobService~d7msitzt] Handling command: queue=library,command=start,force=undefined immich_postgres | 2025-07-21 21:00:14.540 UTC [45] LOG: execute <unnamed>: select "sessions"."id", "sessions"."updatedAt", "sessions"."pinExpiresAt", (select to_json(obj) from (select "users"."id", "users"."name", "users"."email", "users"."isAdmin", "users"."quotaUsageInBytes", "users"."quotaSizeInBytes" from "users" where "users"."id" = "sessions"."userId" and "users"."deletedAt" is null) as obj) as "user" from "sessions" where "sessions"."token" = $1 and ("sessions"."expiresAt" is null or "sessions"."expiresAt" > $2) immich_postgres | 2025-07-21 21:00:14.540 UTC [45] DETAIL: parameters: $1 = '03g4IgxWwa/4tUj0kqm/g7M+eS5yQoLoXydt3QjGCFE=', $2 = '2025-07-21 21:00:14.539+00' immich_server | [Nest] 16 - 07/21/2025, 9:00:14 PM DEBUG [Api:LoggingInterceptor~d7msitzt] PUT /api/jobs/library 200 1.83ms ::ffff:192.168.65.1 immich_server | [Nest] 16 - 07/21/2025, 9:00:14 PM VERBOSE [Api:LoggingInterceptor~d7msitzt] {"command":"start"} immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] Initiating scan of all external libraries... immich_postgres | 2025-07-21 21:00:14.543 UTC [52] LOG: statement: select "libraries".* from "libraries" order by "createdAt" asc immich_postgres | 2025-07-21 21:00:14.543 UTC [64] LOG: statement: select "libraries".* from "libraries" where "libraries"."deletedAt" is not null order by "createdAt" asc immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] Checking for any libraries pending deletion... immich_postgres | 2025-07-21 21:00:14.545 UTC [63] LOG: execute <unnamed>: select "libraries".* from "libraries" where "libraries"."id" = $1 and "libraries"."deletedAt" is null immich_postgres | 2025-07-21 21:00:14.545 UTC [63] DETAIL: parameters: $1 = '2e07fb58-bc83-418b-912b-c67836162a80' immich_postgres | 2025-07-21 21:00:14.546 UTC [52] LOG: execute <unnamed>: select count(*) as "count" from "assets" where "libraryId" = $1::uuid immich_postgres | 2025-07-21 21:00:14.546 UTC [52] DETAIL: parameters: $1 = '2e07fb58-bc83-418b-912b-c67836162a80' immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] Checking 2 asset(s) against import paths and exclusion patterns in library 2e07fb58-bc83-418b-912b-c67836162a80... immich_postgres | 2025-07-21 21:00:14.546 UTC [65] LOG: execute <unnamed>: select "libraries".* from "libraries" where "libraries"."id" = $1 and "libraries"."deletedAt" is null immich_postgres | 2025-07-21 21:00:14.546 UTC [65] DETAIL: parameters: $1 = '2e07fb58-bc83-418b-912b-c67836162a80' immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM DEBUG [Microservices:LibraryService] Validating import paths for library 2e07fb58-bc83-418b-912b-c67836162a80... immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] Starting disk crawl of 1 import path(s) for library 2e07fb58-bc83-418b-912b-c67836162a80... immich_postgres | 2025-07-21 21:00:14.551 UTC [64] LOG: execute <unnamed>: update "assets" set "isOffline" = $1, "deletedAt" = $2 where "isOffline" = $3 and "isExternal" = $4 and "libraryId" = $5::uuid and (not "originalPath" like $6 or ("originalPath" like $7 or "originalPath" like $8 or "originalPath" like $9 or "originalPath" like $10)) immich_postgres | 2025-07-21 21:00:14.551 UTC [64] DETAIL: parameters: $1 = 't', $2 = '2025-07-21 21:00:14.546+00', $3 = 'f', $4 = 't', $5 = '2e07fb58-bc83-418b-912b-c67836162a80', $6 = '/tmp/extvol/media%', $7 = '%/@eaDir/%', $8 = '%/._%', $9 = '%/#recycle/%', $10 = '%/#snapshot/%' immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] 0 asset(s) out of 2 were offlined due to import paths and/or exclusion pattern(s) in library 2e07fb58-bc83-418b-912b-c67836162a80 immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] Scanning library 2e07fb58-bc83-418b-912b-c67836162a80 for assets missing from disk... immich_postgres | 2025-07-21 21:00:14.552 UTC [63] LOG: execute <unnamed>: select "id" from "assets" where "libraryId" = $1 immich_postgres | 2025-07-21 21:00:14.552 UTC [63] DETAIL: parameters: $1 = '2e07fb58-bc83-418b-912b-c67836162a80' immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] Queued check of 2 of 2 (100.0 %) existing asset(s) so far in library 2e07fb58-bc83-418b-912b-c67836162a80 immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] Finished queuing 2 asset check(s) for library 2e07fb58-bc83-418b-912b-c67836162a80 immich_postgres | 2025-07-21 21:00:14.554 UTC [52] LOG: execute <unnamed>: select "assets"."id", "assets"."isOffline", "assets"."libraryId", "assets"."originalPath", "assets"."status", "assets"."fileModifiedAt" from "assets" where "assets"."id" = any($1::uuid[]) immich_postgres | 2025-07-21 21:00:14.554 UTC [52] DETAIL: parameters: $1 = '{379bd0ae-9f77-4720-8744-b7cfda56fba7,85e0945d-3452-4cef-bcc0-1f1b1590a47d}' immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM DEBUG [Microservices:LibraryService] Checking batch of 2 existing asset(s) in library 2e07fb58-bc83-418b-912b-c67836162a80 immich_postgres | 2025-07-21 21:00:14.554 UTC [65] LOG: execute <unnamed>: select "path" from unnest(array[$1, $2]::text[]) as "path" where not exists (select "originalPath" from "assets" where "assets"."originalPath" = "path" and "libraryId" = $3::uuid and "isExternal" = $4) immich_postgres | 2025-07-21 21:00:14.554 UTC [65] DETAIL: parameters: $1 = '/tmp/extvol/media/renamed/img.heic', $2 = '/tmp/extvol/media/renamed/img.mov', $3 = '2e07fb58-bc83-418b-912b-c67836162a80', $4 = 't' immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM DEBUG [Microservices:LibraryService] Asset /tmp/extvol/media/live/img.mov is no longer on disk or is inaccessible because of permissions, marking offline in library 2e07fb58-bc83-418b-912b-c67836162a80 immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM DEBUG [Microservices:LibraryService] Asset /tmp/extvol/media/live/img.heic is no longer on disk or is inaccessible because of permissions, marking offline in library 2e07fb58-bc83-418b-912b-c67836162a80 immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] Crawled 2 file(s) so far: 2 of current batch of 2 will be imported to library 2e07fb58-bc83-418b-912b-c67836162a80... immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] Finished disk crawl, 2 file(s) found on disk and queued 2 file(s) for import into 2e07fb58-bc83-418b-912b-c67836162a80 immich_postgres | 2025-07-21 21:00:14.555 UTC [64] LOG: execute <unnamed>: update "assets" set "isOffline" = $1, "deletedAt" = $2 where "id" = any($3::uuid[]) immich_postgres | 2025-07-21 21:00:14.555 UTC [64] DETAIL: parameters: $1 = 't', $2 = '2025-07-21 21:00:14.554+00', $3 = '{379bd0ae-9f77-4720-8744-b7cfda56fba7,85e0945d-3452-4cef-bcc0-1f1b1590a47d}' immich_postgres | 2025-07-21 21:00:14.555 UTC [63] LOG: execute <unnamed>: update "libraries" set "refreshedAt" = $1 where "libraries"."id" = $2 returning * immich_postgres | 2025-07-21 21:00:14.555 UTC [63] DETAIL: parameters: $1 = '2025-07-21 21:00:14.555+00', $2 = '2e07fb58-bc83-418b-912b-c67836162a80' immich_postgres | 2025-07-21 21:00:14.556 UTC [52] LOG: execute <unnamed>: select "libraries".* from "libraries" where "libraries"."id" = $1 and "libraries"."deletedAt" is null immich_postgres | 2025-07-21 21:00:14.556 UTC [52] DETAIL: parameters: $1 = '2e07fb58-bc83-418b-912b-c67836162a80' immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] Checked existing asset(s): 2 offlined, 0 onlined, 0 updated, 0 unchanged of current batch of 2 (Total progress: 2 of 2, 100.0 %) in library 2e07fb58-bc83-418b-912b-c67836162a80. immich_postgres | 2025-07-21 21:00:14.557 UTC [65] LOG: execute <unnamed>: insert into "assets" ("ownerId", "libraryId", "checksum", "originalPath", "fileCreatedAt", "fileModifiedAt", "localDateTime", "deviceAssetId", "deviceId", "type", "originalFileName", "isExternal", "livePhotoVideoId") values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13), ($14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26) returning * immich_postgres | 2025-07-21 21:00:14.557 UTC [65] DETAIL: parameters: $1 = '00f8b213-f731-42ef-9bf7-344756c9b437', $2 = '2e07fb58-bc83-418b-912b-c67836162a80', $3 = '\xdb2e9437777aeb0d0d01183dec916bbfa2506e70', $4 = '/tmp/extvol/media/renamed/img.heic', $5 = '2025-07-21 20:51:41.745+00', $6 = '2025-07-21 20:51:41.745+00', $7 = '2025-07-21 20:51:41.745+00', $8 = 'img.heic', $9 = 'Library Import', $10 = 'IMAGE', $11 = 'img.heic', $12 = 't', $13 = NULL, $14 = '00f8b213-f731-42ef-9bf7-344756c9b437', $15 = '2e07fb58-bc83-418b-912b-c67836162a80', $16 = '\x9a0f357f0f1d9f99b3b1475186d869315486e473', $17 = '/tmp/extvol/media/renamed/img.mov', $18 = '2025-07-21 20:51:41.747+00', $19 = '2025-07-21 20:51:41.747+00', $20 = '2025-07-21 20:51:41.747+00', $21 = 'img.mov', $22 = 'Library Import', $23 = 'VIDEO', $24 = 'img.mov', $25 = 't', $26 = NULL immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:LibraryService] Imported 2 (2 done so far) file(s) into library 2e07fb58-bc83-418b-912b-c67836162a80 immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM DEBUG [Microservices:LibraryService] Queuing sidecar discovery for 2 asset(s) immich_postgres | 2025-07-21 21:00:14.560 UTC [52] LOG: execute <unnamed>: select "assets".* from "assets" where "assets"."id" = any($1::uuid[]) immich_postgres | 2025-07-21 21:00:14.560 UTC [52] DETAIL: parameters: $1 = '{349bbc25-66cd-481b-81b7-ee4ed100d63b}' immich_postgres | 2025-07-21 21:00:14.560 UTC [63] LOG: execute <unnamed>: select "assets".* from "assets" where "assets"."id" = any($1::uuid[]) immich_postgres | 2025-07-21 21:00:14.560 UTC [63] DETAIL: parameters: $1 = '{ce124416-1b27-4195-a0c7-0c291d9f9bf2}' immich_postgres | 2025-07-21 21:00:14.561 UTC [64] LOG: execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "sidecarPath" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" immich_postgres | 2025-07-21 21:00:14.561 UTC [64] DETAIL: parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b', $2 = '/tmp/extvol/media/renamed/img.xmp', $3 = '349bbc25-66cd-481b-81b7-ee4ed100d63b' immich_postgres | 2025-07-21 21:00:14.561 UTC [65] LOG: execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "sidecarPath" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" immich_postgres | 2025-07-21 21:00:14.561 UTC [65] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = '/tmp/extvol/media/renamed/img.xmp', $3 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_postgres | 2025-07-21 21:00:14.563 UTC [52] LOG: execute <unnamed>: select "assets"."id", "assets"."checksum", "assets"."deviceAssetId", "assets"."deviceId", "assets"."fileCreatedAt", "assets"."fileModifiedAt", "assets"."isExternal", "assets"."visibility", "assets"."libraryId", "assets"."livePhotoVideoId", "assets"."localDateTime", "assets"."originalFileName", "assets"."originalPath", "assets"."ownerId", "assets"."sidecarPath", "assets"."type", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".* from "asset_faces" where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" where "assets"."id" = $1 immich_postgres | 2025-07-21 21:00:14.563 UTC [52] DETAIL: parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b' immich_postgres | 2025-07-21 21:00:14.563 UTC [63] LOG: execute <unnamed>: select "assets"."id", "assets"."checksum", "assets"."deviceAssetId", "assets"."deviceId", "assets"."fileCreatedAt", "assets"."fileModifiedAt", "assets"."isExternal", "assets"."visibility", "assets"."libraryId", "assets"."livePhotoVideoId", "assets"."localDateTime", "assets"."originalFileName", "assets"."originalPath", "assets"."ownerId", "assets"."sidecarPath", "assets"."type", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".* from "asset_faces" where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" where "assets"."id" = $1 immich_postgres | 2025-07-21 21:00:14.563 UTC [63] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_server | <exif details omitted> immich_postgres | 2025-07-21 21:00:14.820 UTC [63] LOG: statement: begin immich_postgres | 2025-07-21 21:00:14.821 UTC [63] LOG: execute <unnamed>: delete from "tag_asset" where "assetsId" = $1 immich_postgres | 2025-07-21 21:00:14.821 UTC [63] DETAIL: parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b' immich_postgres | 2025-07-21 21:00:14.821 UTC [52] LOG: execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "duration" = $2, "localDateTime" = $3, "fileCreatedAt" = $4, "fileModifiedAt" = $5 where "id" = $6::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" immich_postgres | 2025-07-21 21:00:14.821 UTC [52] DETAIL: parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b', $2 = NULL, $3 = '2019-12-12 20:47:22.128+00', $4 = '2019-12-13 01:47:22.128+00', $5 = '2025-07-21 20:51:41.745+00', $6 = '349bbc25-66cd-481b-81b7-ee4ed100d63b' immich_postgres | 2025-07-21 21:00:14.821 UTC [63] LOG: statement: commit immich_postgres | 2025-07-21 21:00:14.823 UTC [64] LOG: execute <unnamed>: select "assets"."id", "assets"."ownerId" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "id" != $1::uuid and "ownerId" = $2::uuid and "type" = $3 and "exif"."livePhotoCID" = $4 limit $5 immich_postgres | 2025-07-21 21:00:14.823 UTC [64] DETAIL: parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b', $2 = '00f8b213-f731-42ef-9bf7-344756c9b437', $3 = 'VIDEO', $4 = 'CA20385D-6106-49C9-ACF5-2F8098F4B390', $5 = '1' immich_postgres | 2025-07-21 21:00:14.824 UTC [52] LOG: execute <unnamed>: delete from "albums_assets_assets" where "albums_assets_assets"."assetsId" in ($1) immich_postgres | 2025-07-21 21:00:14.824 UTC [52] DETAIL: parameters: $1 = '379bd0ae-9f77-4720-8744-b7cfda56fba7' immich_postgres | 2025-07-21 21:00:14.824 UTC [65] LOG: execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "visibility" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" immich_postgres | 2025-07-21 21:00:14.824 UTC [65] DETAIL: parameters: $1 = '379bd0ae-9f77-4720-8744-b7cfda56fba7', $2 = 'hidden', $3 = '379bd0ae-9f77-4720-8744-b7cfda56fba7' immich_postgres | 2025-07-21 21:00:14.824 UTC [63] LOG: execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "livePhotoVideoId" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" immich_postgres | 2025-07-21 21:00:14.824 UTC [63] DETAIL: parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b', $2 = '379bd0ae-9f77-4720-8744-b7cfda56fba7', $3 = '349bbc25-66cd-481b-81b7-ee4ed100d63b' immich_postgres | 2025-07-21 21:00:14.825 UTC [64] LOG: execute <unnamed>: insert into "asset_job_status" ("assetId", "metadataExtractedAt") values ($1::uuid, $2) on conflict ("assetId") do update set "metadataExtractedAt" = "excluded"."metadataExtractedAt" immich_postgres | 2025-07-21 21:00:14.825 UTC [64] DETAIL: parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b', $2 = '2025-07-21 21:00:14.825+00' immich_postgres | 2025-07-21 21:00:14.827 UTC [52] LOG: execute <unnamed>: select "assets"."id", "assets"."ownerId", "assets"."type", "assets"."checksum", "assets"."originalPath", "assets"."isExternal", "assets"."sidecarPath", "assets"."originalFileName", "assets"."livePhotoVideoId", "assets"."fileCreatedAt", "exif"."timeZone", "exif"."fileSizeInByte" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "assets"."deletedAt" is null and "assets"."id" = $1 immich_postgres | 2025-07-21 21:00:14.827 UTC [52] DETAIL: parameters: $1 = '349bbc25-66cd-481b-81b7-ee4ed100d63b' immich_postgres | 2025-07-21 21:00:14.828 UTC [65] LOG: execute <unnamed>: select "id", "name", "email", "avatarColor", "profileImagePath", "profileChangedAt", "createdAt", "updatedAt", "deletedAt", "isAdmin", "status", "oauthId", "profileImagePath", "shouldChangePassword", "storageLabel", "quotaSizeInBytes", "quotaUsageInBytes", (select coalesce(json_agg(agg), '[]') from (select "user_metadata"."key", "user_metadata"."value" from "user_metadata" where "users"."id" = "user_metadata"."userId") as agg) as "metadata" from "users" where "users"."id" = $1 and "users"."deletedAt" is null immich_postgres | 2025-07-21 21:00:14.828 UTC [65] DETAIL: parameters: $1 = '00f8b213-f731-42ef-9bf7-344756c9b437' immich_postgres | 2025-07-21 21:00:14.828 UTC [63] LOG: execute <unnamed>: select "assets"."id", "assets"."ownerId", "assets"."type", "assets"."checksum", "assets"."originalPath", "assets"."isExternal", "assets"."sidecarPath", "assets"."originalFileName", "assets"."livePhotoVideoId", "assets"."fileCreatedAt", "exif"."timeZone", "exif"."fileSizeInByte" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "assets"."deletedAt" is null and "assets"."id" = $1 immich_postgres | 2025-07-21 21:00:14.828 UTC [63] DETAIL: parameters: $1 = '379bd0ae-9f77-4720-8744-b7cfda56fba7' immich_server | <exif details omitted> immich_postgres | 2025-07-21 21:00:14.913 UTC [63] LOG: statement: begin immich_postgres | 2025-07-21 21:00:14.914 UTC [63] LOG: execute <unnamed>: delete from "tag_asset" where "assetsId" = $1 immich_postgres | 2025-07-21 21:00:14.914 UTC [63] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_postgres | 2025-07-21 21:00:14.914 UTC [65] LOG: execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "duration" = $2, "localDateTime" = $3, "fileCreatedAt" = $4, "fileModifiedAt" = $5 where "id" = $6::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" immich_postgres | 2025-07-21 21:00:14.914 UTC [65] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = '00:00:02.153', $3 = '2019-12-12 20:47:21+00', $4 = '2019-12-13 01:47:21+00', $5 = '2025-07-21 20:51:41.747+00', $6 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_postgres | 2025-07-21 21:00:14.915 UTC [63] LOG: statement: commit immich_postgres | 2025-07-21 21:00:14.917 UTC [64] LOG: execute <unnamed>: select "assets"."id", "assets"."ownerId" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "id" != $1::uuid and "ownerId" = $2::uuid and "type" = $3 and "exif"."livePhotoCID" = $4 limit $5 immich_postgres | 2025-07-21 21:00:14.917 UTC [64] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = '00f8b213-f731-42ef-9bf7-344756c9b437', $3 = 'IMAGE', $4 = 'CA20385D-6106-49C9-ACF5-2F8098F4B390', $5 = '1' immich_postgres | 2025-07-21 21:00:14.918 UTC [52] LOG: execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "visibility" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" immich_postgres | 2025-07-21 21:00:14.918 UTC [52] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = 'hidden', $3 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_postgres | 2025-07-21 21:00:14.918 UTC [63] LOG: execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "livePhotoVideoId" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" immich_postgres | 2025-07-21 21:00:14.918 UTC [63] DETAIL: parameters: $1 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d', $2 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $3 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d' immich_postgres | 2025-07-21 21:00:14.919 UTC [65] LOG: execute <unnamed>: delete from "albums_assets_assets" where "albums_assets_assets"."assetsId" in ($1) immich_postgres | 2025-07-21 21:00:14.919 UTC [65] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_postgres | 2025-07-21 21:00:14.920 UTC [64] LOG: execute <unnamed>: insert into "asset_job_status" ("assetId", "metadataExtractedAt") values ($1::uuid, $2) on conflict ("assetId") do update set "metadataExtractedAt" = "excluded"."metadataExtractedAt" immich_postgres | 2025-07-21 21:00:14.920 UTC [64] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = '2025-07-21 21:00:14.919+00' immich_postgres | 2025-07-21 21:00:14.921 UTC [52] LOG: execute <unnamed>: select "assets"."id", "assets"."ownerId", "assets"."type", "assets"."checksum", "assets"."originalPath", "assets"."isExternal", "assets"."sidecarPath", "assets"."originalFileName", "assets"."livePhotoVideoId", "assets"."fileCreatedAt", "exif"."timeZone", "exif"."fileSizeInByte" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "assets"."deletedAt" is null and "assets"."id" = $1 immich_postgres | 2025-07-21 21:00:14.921 UTC [52] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_postgres | 2025-07-21 21:00:14.922 UTC [65] LOG: execute <unnamed>: select "id", "name", "email", "avatarColor", "profileImagePath", "profileChangedAt", "createdAt", "updatedAt", "deletedAt", "isAdmin", "status", "oauthId", "profileImagePath", "shouldChangePassword", "storageLabel", "quotaSizeInBytes", "quotaUsageInBytes", (select coalesce(json_agg(agg), '[]') from (select "user_metadata"."key", "user_metadata"."value" from "user_metadata" where "users"."id" = "user_metadata"."userId") as agg) as "metadata" from "users" where "users"."id" = $1 and "users"."deletedAt" is null immich_postgres | 2025-07-21 21:00:14.922 UTC [65] DETAIL: parameters: $1 = '00f8b213-f731-42ef-9bf7-344756c9b437' immich_postgres | 2025-07-21 21:00:14.924 UTC [63] LOG: execute <unnamed>: select "assets"."id", "assets"."visibility", "assets"."originalFileName", "assets"."originalPath", "assets"."ownerId", "assets"."thumbhash", "assets"."type", (select coalesce(json_agg(agg), '[]') from (select "asset_files"."id", "asset_files"."path", "asset_files"."type" from "asset_files" where "asset_files"."assetId" = "assets"."id") as agg) as "files", to_json("exif") as "exifInfo" from "assets" inner join "exif" on "assets"."id" = "exif"."assetId" where "assets"."id" = $1 immich_postgres | 2025-07-21 21:00:14.924 UTC [63] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM VERBOSE [Microservices:MediaService] Thumbnail generation skipped for asset ce124416-1b27-4195-a0c7-0c291d9f9bf2: not visible immich_postgres | 2025-07-21 21:00:14.926 UTC [64] LOG: execute <unnamed>: select "assets".*, (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces", (select coalesce(json_agg(agg), '[]') from (select "tags"."id", "tags"."value", "tags"."createdAt", "tags"."updatedAt", "tags"."color", "tags"."parentId" from "tags" inner join "tag_asset" on "tags"."id" = "tag_asset"."tagsId" where "assets"."id" = "tag_asset"."assetsId") as agg) as "tags", to_json("exif") as "exifInfo" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" where "assets"."id" = any($1::uuid[]) immich_postgres | 2025-07-21 21:00:14.926 UTC [64] DETAIL: parameters: $1 = '{ce124416-1b27-4195-a0c7-0c291d9f9bf2}' immich_postgres | 2025-07-21 21:00:14.928 UTC [52] LOG: execute <unnamed>: select "assets"."id", "assets"."ownerId", "assets"."originalPath", "assets"."encodedVideoPath" from "assets" where "assets"."id" = $1 and "assets"."type" = $2 immich_postgres | 2025-07-21 21:00:14.928 UTC [52] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = 'VIDEO' immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM LOG [Microservices:MediaService] Transcoding video ce124416-1b27-4195-a0c7-0c291d9f9bf2 without hardware acceleration immich_server | [Nest] 6 - 07/21/2025, 9:00:14 PM DEBUG [Microservices:MediaRepository] ffmpeg -n 10 /usr/bin/ffmpeg -i /tmp/extvol/media/renamed/img.mov -y -c:v h264 -c:a copy -movflags faststart -fps_mode passthrough -map 0:0 -map_metadata -1 -map 0:1 -v verbose -vf scale=-2:720 -preset ultrafast -crf 23 upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/ce/12/ce124416-1b27-4195-a0c7-0c291d9f9bf2.mp4 immich_server | [Nest] 6 - 07/21/2025, 9:00:15 PM DEBUG [Microservices:MediaRepository] Transcoding 100.00% done for output ce124416-1b27-4195-a0c7-0c291d9f9bf2.mp4 immich_server | [Nest] 6 - 07/21/2025, 9:00:15 PM LOG [Microservices:MediaService] Successfully encoded ce124416-1b27-4195-a0c7-0c291d9f9bf2 immich_postgres | 2025-07-21 21:00:15.144 UTC [65] LOG: execute <unnamed>: with "assets" as (update "assets" set "id" = $1, "encodedVideoPath" = $2 where "id" = $3::uuid returning *) select "assets".*, to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" immich_postgres | 2025-07-21 21:00:15.144 UTC [65] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2', $2 = 'upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/ce/12/ce124416-1b27-4195-a0c7-0c291d9f9bf2.mp4', $3 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' ``` </details> ### Step 3. Delete the offlined live photo from trash. External library content on disk: - ✅ Offline HEIC, MOV, XMP were removed - ✅ Online HEIC is present - ❌ Online MOV, XMP were removed ```sh tree /tmp/extvol/media /tmp/extvol/media └── renamed └── img.heic ``` Assets upon deleting offline live photo from trash: - ✅ Offline HEIC was removed - ❌ Offline MOV is present - ✅ Online HEIC is present - ❌ Online MOV was removed - ❌ Image->video is cross-linked / mixed up: `renamed/img.heic -> live/img.mov` ```sql -[ RECORD 1 ]----+--------------------------------------------------------------------------------------------------------- id | 379bd0ae-9f77-4720-8744-b7cfda56fba7 type | VIDEO originalPath | /tmp/extvol/media/live/img.mov isOffline | t -[ RECORD 2 ]----+--------------------------------------------------------------------------------------------------------- type | IMAGE originalPath | /tmp/extvol/media/renamed/img.heic livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7 isOffline | f ``` DB `assets`: <details> <summary>select * from assets order by "originalPath"; (2 assets)</summary> ```sql -[ RECORD 1 ]----+--------------------------------------------------------------------------------------------------------- id | 379bd0ae-9f77-4720-8744-b7cfda56fba7 deviceAssetId | img.mov ownerId | 00f8b213-f731-42ef-9bf7-344756c9b437 deviceId | Library Import type | VIDEO originalPath | /tmp/extvol/media/live/img.mov fileCreatedAt | 2019-12-13 01:47:21+00 fileModifiedAt | 2025-07-21 20:51:41.747+00 isFavorite | f duration | 00:00:02.153 encodedVideoPath | upload/encoded-video/00f8b213-f731-42ef-9bf7-344756c9b437/37/9b/379bd0ae-9f77-4720-8744-b7cfda56fba7.mp4 checksum | \x1ddd617b09f39d47d2b00d2035fa49fd3ec5ff24 livePhotoVideoId | updatedAt | 2025-07-21 21:00:14.824562+00 createdAt | 2025-07-21 20:51:49.819066+00 originalFileName | img.mov sidecarPath | /tmp/extvol/media/live/img.xmp thumbhash | \x58f50d1d805676788977788089b88778c0a5fe7a6e isOffline | t libraryId | 2e07fb58-bc83-418b-912b-c67836162a80 isExternal | t deletedAt | 2025-07-21 21:00:14.554+00 localDateTime | 2019-12-12 20:47:21+00 stackId | duplicateId | status | active updateId | 01982ec9-8268-74ed-8c5f-d7afa1f42018 visibility | hidden -[ RECORD 2 ]----+--------------------------------------------------------------------------------------------------------- id | 349bbc25-66cd-481b-81b7-ee4ed100d63b deviceAssetId | img.heic ownerId | 00f8b213-f731-42ef-9bf7-344756c9b437 deviceId | Library Import type | IMAGE originalPath | /tmp/extvol/media/renamed/img.heic fileCreatedAt | 2019-12-13 01:47:22.128+00 fileModifiedAt | 2025-07-21 20:51:41.745+00 isFavorite | f duration | encodedVideoPath | checksum | \xdb2e9437777aeb0d0d01183dec916bbfa2506e70 livePhotoVideoId | 379bd0ae-9f77-4720-8744-b7cfda56fba7 updatedAt | 2025-07-21 21:00:14.824671+00 createdAt | 2025-07-21 21:00:14.557112+00 originalFileName | img.heic sidecarPath | /tmp/extvol/media/renamed/img.xmp thumbhash | isOffline | f libraryId | 2e07fb58-bc83-418b-912b-c67836162a80 isExternal | t deletedAt | localDateTime | 2019-12-12 20:47:22.128+00 stackId | duplicateId | status | active updateId | 01982ec9-8268-7e20-8fe5-efa195ffb549 visibility | timeline ``` </details> Logs: <details> <summary>Log of deleting offlined asset from trash</summary> ```sql immich_postgres | 2025-07-21 21:41:53.372 UTC [45] LOG: execute <unnamed>: select "sessions"."id", "sessions"."updatedAt", "sessions"."pinExpiresAt", (select to_json(obj) from (select "users"."id", "users"."name", "users"."email", "users"."isAdmin", "users"."quotaUsageInBytes", "users"."quotaSizeInBytes" from "users" where "users"."id" = "sessions"."userId" and "users"."deletedAt" is null) as obj) as "user" from "sessions" where "sessions"."token" = $1 and ("sessions"."expiresAt" is null or "sessions"."expiresAt" > $2) immich_postgres | 2025-07-21 21:41:53.372 UTC [45] DETAIL: parameters: $1 = '03g4IgxWwa/4tUj0kqm/g7M+eS5yQoLoXydt3QjGCFE=', $2 = '2025-07-21 21:41:53.372+00' immich_postgres | 2025-07-21 21:41:53.374 UTC [46] LOG: execute <unnamed>: select "assets"."id" from "assets" where "assets"."id" in ($1) and "assets"."ownerId" = $2 and "assets"."visibility" != $3 immich_postgres | 2025-07-21 21:41:53.374 UTC [46] DETAIL: parameters: $1 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d', $2 = '00f8b213-f731-42ef-9bf7-344756c9b437', $3 = 'locked' immich_postgres | 2025-07-21 21:41:53.374 UTC [45] LOG: execute <unnamed>: update "assets" set "deletedAt" = $1, "status" = $2 where "id" = any($3::uuid[]) immich_postgres | 2025-07-21 21:41:53.374 UTC [45] DETAIL: parameters: $1 = '2025-07-21 21:41:53.374+00', $2 = 'deleted', $3 = '{85e0945d-3452-4cef-bcc0-1f1b1590a47d}' immich_server | [Nest] 16 - 07/21/2025, 9:41:53 PM DEBUG [Api:LoggingInterceptor~4oldyr8y] DELETE /api/assets 204 8.05ms ::ffff:192.168.65.1 immich_server | [Nest] 16 - 07/21/2025, 9:41:53 PM VERBOSE [Api:LoggingInterceptor~4oldyr8y] {"ids":["85e0945d-3452-4cef-bcc0-1f1b1590a47d"],"force":true} immich_postgres | 2025-07-21 21:41:53.397 UTC [166] LOG: execute wzjz461vydd1: immich_postgres | select b.oid, b.typarray immich_postgres | from pg_catalog.pg_type a immich_postgres | left join pg_catalog.pg_type b on b.oid = a.typelem immich_postgres | where a.typcategory = 'A' immich_postgres | group by b.oid, b.typarray immich_postgres | order by b.oid immich_postgres | immich_postgres | 2025-07-21 21:41:53.403 UTC [166] LOG: execute <unnamed>: select "id" from "assets" where "status" = $1 immich_postgres | 2025-07-21 21:41:53.403 UTC [166] DETAIL: parameters: $1 = 'deleted' immich_server | [Nest] 6 - 07/21/2025, 9:41:53 PM DEBUG [Microservices:TrashService] Queueing 1 asset(s) for deletion from the trash immich_server | [Nest] 6 - 07/21/2025, 9:41:53 PM LOG [Microservices:TrashService] Queued 1 asset(s) for deletion from the trash immich_postgres | 2025-07-21 21:41:53.413 UTC [166] LOG: execute <unnamed>: select "assets"."id", "assets"."visibility", "assets"."libraryId", "assets"."ownerId", "assets"."livePhotoVideoId", "assets"."sidecarPath", "assets"."encodedVideoPath", "assets"."originalPath", to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces", (select coalesce(json_agg(agg), '[]') from (select "asset_files"."id", "asset_files"."path", "asset_files"."type" from "asset_files" where "asset_files"."assetId" = "assets"."id") as agg) as "files", to_json("stacked_assets") as "stack" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" left join "asset_stack" on "asset_stack"."id" = "assets"."stackId" left join lateral (select "asset_stack"."id", "asset_stack"."primaryAssetId", array_agg("stacked") as "assets" from "assets" as "stacked" where "stacked"."deletedAt" is not null and "stacked"."visibility" = $1 and "stacked"."stackId" = "asset_stack"."id" group by "asset_stack"."id") as "stacked_assets" on "asset_stack"."id" is not null where "assets"."id" = $2 immich_postgres | 2025-07-21 21:41:53.413 UTC [166] DETAIL: parameters: $1 = 'timeline', $2 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d' immich_postgres | 2025-07-21 21:41:53.414 UTC [166] LOG: execute <unnamed>: delete from "assets" where "id" = $1::uuid immich_postgres | 2025-07-21 21:41:53.414 UTC [166] DETAIL: parameters: $1 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d' immich_server | [Nest] 6 - 07/21/2025, 9:41:53 PM DEBUG [Microservices:StorageTemplateService] Cleaning up move history for asset 85e0945d-3452-4cef-bcc0-1f1b1590a47d immich_postgres | 2025-07-21 21:41:53.423 UTC [166] LOG: execute <unnamed>: delete from "move_history" where "move_history"."pathType" = 'original' and "entityId" = $1 immich_postgres | 2025-07-21 21:41:53.423 UTC [166] DETAIL: parameters: $1 = '85e0945d-3452-4cef-bcc0-1f1b1590a47d' immich_postgres | 2025-07-21 21:41:53.424 UTC [166] LOG: execute <unnamed>: select count(*) as "count" from "assets" where "livePhotoVideoId" = $1::uuid immich_postgres | 2025-07-21 21:41:53.424 UTC [166] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_postgres | 2025-07-21 21:41:53.427 UTC [166] LOG: execute <unnamed>: select "assets"."id", "assets"."visibility", "assets"."libraryId", "assets"."ownerId", "assets"."livePhotoVideoId", "assets"."sidecarPath", "assets"."encodedVideoPath", "assets"."originalPath", to_json("exif") as "exifInfo", (select coalesce(json_agg(agg), '[]') from (select "asset_faces".*, "person" as "person" from "asset_faces" left join lateral (select "person".* from "person" where "asset_faces"."personId" = "person"."id") as "person" on true where "asset_faces"."assetId" = "assets"."id" and "asset_faces"."deletedAt" is null) as agg) as "faces", (select coalesce(json_agg(agg), '[]') from (select "asset_files"."id", "asset_files"."path", "asset_files"."type" from "asset_files" where "asset_files"."assetId" = "assets"."id") as agg) as "files", to_json("stacked_assets") as "stack" from "assets" left join "exif" on "assets"."id" = "exif"."assetId" left join "asset_stack" on "asset_stack"."id" = "assets"."stackId" left join lateral (select "asset_stack"."id", "asset_stack"."primaryAssetId", array_agg("stacked") as "assets" from "assets" as "stacked" where "stacked"."deletedAt" is not null and "stacked"."visibility" = $1 and "stacked"."stackId" = "asset_stack"."id" group by "asset_stack"."id") as "stacked_assets" on "asset_stack"."id" is not null where "assets"."id" = $2 immich_postgres | 2025-07-21 21:41:53.427 UTC [166] DETAIL: parameters: $1 = 'timeline', $2 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_postgres | 2025-07-21 21:41:53.428 UTC [166] LOG: execute <unnamed>: delete from "assets" where "id" = $1::uuid immich_postgres | 2025-07-21 21:41:53.428 UTC [166] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_server | [Nest] 6 - 07/21/2025, 9:41:53 PM DEBUG [Microservices:StorageTemplateService] Cleaning up move history for asset ce124416-1b27-4195-a0c7-0c291d9f9bf2 immich_postgres | 2025-07-21 21:41:53.430 UTC [166] LOG: execute <unnamed>: delete from "move_history" where "move_history"."pathType" = 'original' and "entityId" = $1 immich_postgres | 2025-07-21 21:41:53.430 UTC [166] DETAIL: parameters: $1 = 'ce124416-1b27-4195-a0c7-0c291d9f9bf2' immich_server | [Nest] 6 - 07/21/2025, 9:41:53 PM WARN [Microservices:StorageRepository] File /tmp/extvol/media/live/img.xmp does not exist. immich_server | [Nest] 6 - 07/21/2025, 9:41:53 PM WARN [Microservices:StorageRepository] File /tmp/extvol/media/live/img.heic does not exist. immich_server | [Nest] 6 - 07/21/2025, 9:41:55 PM DEBUG [Microservices:VersionService] Running version check immich_postgres | 2025-07-21 21:41:55.189 UTC [166] LOG: execute <unnamed>: select "value" from "system_metadata" where "key" = $1 immich_postgres | 2025-07-21 21:41:55.189 UTC [166] DETAIL: parameters: $1 = 'version-check-state' immich_postgres | 2025-07-21 21:41:55.440 UTC [166] LOG: execute <unnamed>: insert into "system_metadata" ("key", "value") values ($1, $2) on conflict ("key") do update set "value" = $3 immich_postgres | 2025-07-21 21:41:55.440 UTC [166] DETAIL: parameters: $1 = 'version-check-state', $2 = '{"checkedAt": "2025-07-21T21:41:55.438Z", "releaseVersion": "v1.135.3"}', $3 = '{"checkedAt": "2025-07-21T21:41:55.438Z", "releaseVersion": "v1.135.3"}' immich_server | [Nest] 16 - 07/21/2025, 9:42:13 PM DEBUG [Api:LoggingInterceptor~uvj4mufd] GET /api/server/ping 200 0.14ms ::ffff:127.0.0.1 ``` </details>
Author
Owner

@skatsubo commented on GitHub (Jul 21, 2025):

Somewhat related: https://github.com/immich-app/immich/issues/17731#issuecomment-2902651034

@skatsubo commented on GitHub (Jul 21, 2025): Somewhat related: https://github.com/immich-app/immich/issues/17731#issuecomment-2902651034
Author
Owner

@AlgorithMikely commented on GitHub (Aug 7, 2025):

I believe the issue is in the asset.repository.ts from line 469

findLivePhotoMatch(options: LivePhotoSearchOptions) {
const { ownerId, otherAssetId, livePhotoCID, type } = options;
return this.db
.selectFrom('asset')
.select(['asset.id', 'asset.ownerId'])
.innerJoin('asset_exif', 'asset.id', 'asset_exif.assetId')
.where('id', '!=', asUuid(otherAssetId))
.where('ownerId', '=', asUuid(ownerId))
.where('type', '=', type)
.where('asset_exif.livePhotoCID', '=', livePhotoCID)
.limit(1)
.executeTakeFirst();
}

Would Replacing the code above with the following code fix the issue?

findLivePhotoMatch(options: LivePhotoSearchOptions) {
const { ownerId, libraryId, otherAssetId, livePhotoCID, type } = options;
return this.db
.selectFrom('asset')
.select(['asset.id', 'asset.ownerId'])
.innerJoin('asset_exif', 'asset.id', 'asset_exif.assetId')
.where('asset.id', '!=', asUuid(otherAssetId))
.where('asset.ownerId', '=', asUuid(ownerId))
.$call((qb) => (libraryId ? qb.where('libraryId', '=', asUuid(libraryId)) : qb.where('libraryId', 'is', null)))
.where('asset.type', '=', type)
.where('asset.isOffline', '=', false)
.where('asset.deletedAt', 'is', null)
.where('asset_exif.livePhotoCID', '=', livePhotoCID)
.limit(1)
.executeTakeFirst();
}

@AlgorithMikely commented on GitHub (Aug 7, 2025): I believe the issue is in the asset.repository.ts from line 469 findLivePhotoMatch(options: LivePhotoSearchOptions) { const { ownerId, otherAssetId, livePhotoCID, type } = options; return this.db .selectFrom('asset') .select(['asset.id', 'asset.ownerId']) .innerJoin('asset_exif', 'asset.id', 'asset_exif.assetId') .where('id', '!=', asUuid(otherAssetId)) .where('ownerId', '=', asUuid(ownerId)) .where('type', '=', type) .where('asset_exif.livePhotoCID', '=', livePhotoCID) .limit(1) .executeTakeFirst(); } Would Replacing the code above with the following code fix the issue? findLivePhotoMatch(options: LivePhotoSearchOptions) { const { ownerId, libraryId, otherAssetId, livePhotoCID, type } = options; return this.db .selectFrom('asset') .select(['asset.id', 'asset.ownerId']) .innerJoin('asset_exif', 'asset.id', 'asset_exif.assetId') .where('asset.id', '!=', asUuid(otherAssetId)) .where('asset.ownerId', '=', asUuid(ownerId)) .$call((qb) => (libraryId ? qb.where('libraryId', '=', asUuid(libraryId)) : qb.where('libraryId', 'is', null))) .where('asset.type', '=', type) .where('asset.isOffline', '=', false) .where('asset.deletedAt', 'is', null) .where('asset_exif.livePhotoCID', '=', livePhotoCID) .limit(1) .executeTakeFirst(); }
Author
Owner

@FunkyKwak commented on GitHub (Aug 20, 2025):

This is scary, I really need to find a way to run the container with a non root user, without deletion rights.

@FunkyKwak commented on GitHub (Aug 20, 2025): This is scary, I really need to find a way to run the container with a non root user, without deletion rights.
Author
Owner

@bo0tzz commented on GitHub (Sep 21, 2025):

The root of this amounts to being a dupe of #16394.

@bo0tzz commented on GitHub (Sep 21, 2025): The root of this amounts to being a dupe of #16394.
Author
Owner

@FunkyKwak commented on GitHub (Sep 21, 2025):

@bo0tzz, if xmp files can be deleted by immich just because I renamed a folder, this is a bug, not something related to the feature request you mentioned!
Xmp files can be managed outside of immich, immich should never delete it!

Or did I understand the issue incorrectly?

@FunkyKwak commented on GitHub (Sep 21, 2025): @bo0tzz, if xmp files can be deleted by immich just because I renamed a folder, this is a bug, not something related to the feature request you mentioned! Xmp files can be managed outside of immich, immich should never delete it! Or did I understand the issue incorrectly?
Author
Owner

@bo0tzz commented on GitHub (Sep 21, 2025):

When you rename the folder, Immich considers the asset as being removed/offline and so (eventually) does the usual cleanup just like if you delete it. It's not aware that the file was actually moved/renamed.

@bo0tzz commented on GitHub (Sep 21, 2025): When you rename the folder, Immich considers the asset as being removed/offline and so (eventually) does the usual cleanup just like if you delete it. It's not aware that the file was actually moved/renamed.
Author
Owner

@FunkyKwak commented on GitHub (Sep 21, 2025):

When you rename the folder, Immich considers the asset as being removed/offline and so (eventually) does the usual cleanup just like if you delete it. It's not aware that the file was actually moved/renamed.

But there are still photos in the folder associated to these xmp. They should not be deleted, no matter what.

I think this is a very dangerous behaviour, especially for people like me, managing xmp files outside of immich, for which these files are particularly valuable. But still, even if the xmp files where generated by Immich, that's still the deletion of the user's work on his pictures.

@FunkyKwak commented on GitHub (Sep 21, 2025): > When you rename the folder, Immich considers the asset as being removed/offline and so (eventually) does the usual cleanup just like if you delete it. It's not aware that the file was actually moved/renamed. But there are still photos in the folder associated to these xmp. They should not be deleted, no matter what. I think this is a very dangerous behaviour, especially for people like me, managing xmp files outside of immich, for which these files are particularly valuable. But still, even if the xmp files where generated by Immich, that's still the deletion of the user's work on his pictures.
Author
Owner

@bo0tzz commented on GitHub (Sep 21, 2025):

Hmmm I think I get what you mean. That's very odd

@bo0tzz commented on GitHub (Sep 21, 2025): Hmmm I think I get what you mean. That's very odd
Author
Owner

@pantra64 commented on GitHub (Sep 21, 2025):

It's not just about the xmp sidecars. The mov files, the actual video files of a live photo, are getting deleted.

@pantra64 commented on GitHub (Sep 21, 2025): It's not just about the xmp sidecars. The mov files, the actual video files of a live photo, are getting deleted.
Author
Owner

@pantra64 commented on GitHub (Oct 2, 2025):

Have to say I'm a bit surprised that Immich just moved to a "stable" release with this issue still unfixed. I seem to notice some confusion in the recent discussion here about the nature of this bug. This is not, I repeat NOT "just" about deleting sidecars - even when that would be bad enough. To put it bluntly: Immich silently and without notice, warning or failsave DELETES actual library files. The issue is reproducible 100%, as described. Since I identified the issue, I have only ever mounted my files as read only, I don't trust immich with any write access to my library anymore. And if I didn't run a fully automated backup every 24 hours of all my files, Immich would have irreversibly deleted the majority of my live-photo videos, without ever telling me. When this kept happening over and over again and I kept restoring files from backup over and over again without a clue for days, it felt like I was going mad, almost doubting the security of my network. As far as bugs go, I'd consider this one high priority.

@pantra64 commented on GitHub (Oct 2, 2025): Have to say I'm a bit surprised that Immich just moved to a "stable" release with this issue still unfixed. I seem to notice some confusion in the recent discussion here about the nature of this bug. This is not, I repeat NOT "just" about deleting sidecars - even when that would be bad enough. To put it bluntly: Immich silently and without notice, warning or failsave DELETES actual library files. The issue is reproducible 100%, as described. Since I identified the issue, I have only ever mounted my files as read only, I don't trust immich with any write access to my library anymore. And if I didn't run a fully automated backup every 24 hours of all my files, Immich would have irreversibly deleted the majority of my live-photo videos, without ever telling me. When this kept happening over and over again and I kept restoring files from backup over and over again without a clue for days, it felt like I was going mad, almost doubting the security of my network. As far as bugs go, I'd consider this one high priority.
Author
Owner

@FunkyKwak commented on GitHub (Feb 5, 2026):

Sorry to ask, but do you know when this will be fixed ?

@FunkyKwak commented on GitHub (Feb 5, 2026): Sorry to ask, but do you know when this will be fixed ?
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/immich#6011
No description provided.