Skip to content

feat(scan): skip formats Immich cannot accept (#95) - #99

Merged
elementalvoid merged 2 commits into
mainfrom
ticket/95-supported-formats
Nov 14, 2026
Merged

elementalvoid merged 2 commits into
mainfrom
ticket/95-supported-formats

Conversation

@elementalvoid

Copy link
Copy Markdown
Owner

Closes #95.

Summary

The client now holds Immich's supported extensions in one list, so a file the
server cannot accept is never a sync item — no state row, no attempt, no
failure.

 scan / watcher (shared skip rule)
   hidden, symlink, temporary, system        skip (as before)
   XMP sidecar                                skip; it rides with its asset
+  extension not in Immich's allowlist        skip; count it for the folder
   everything else                            queue an item
+
+allowlist (crates/sync-core/src/skip.rs)
+  SUPPORTED_MEDIA_EXTENSIONS = 40 image + video extensions, one line to add
 folder row (V14 migration)
   last_scan_ns, last_upload_ns
+  unsupported                  # files the last scan refused
  • Never queued: matching is case-insensitive on the extension; a file with
    no extension, .wma, .mp3, .flac are refused. The sidecar, temporary and
    system rules still win, so an .xmp of a skipped file is skipped with it.
  • Count in the folder detail: Files Immich cannot accept: 3, only when it
    is above zero. Nothing on the dashboard, and the pending/uploaded/failed
    counts do not move. The count lives on the folder row, so it survives a
    restart and the signed-out view (operator decision).
  • Log: one line per scan per folder with the count and the extensions seen
    (info when above zero, debug when zero), per-file detail at debug.
  • Old rows: a row recorded before this rule, for a file the list now
    refuses and holding no server asset, is deleted by the next scan that sees
    the file; the startup requeue no longer sends such a path. A row that holds
    an asset keeps its mapping and version chain (R4).
  • Server stays the authority: a file the list accepts and Immich still
    refuses remains the permanent unsupported_format failure with its readable
    reason.

Files: sync-core/src/{skip,scan,engine,store,status}.rs,
app/src/{status,engine,folder_panel}.rs, SPEC.md R2.2, GLOSSARY.md.

Evidence

  • Before: a .wma in a source folder was queued, answered 415, and landed
    in Failed as a dead letter (issue Supported file formats #95).
    After: sync-core::it engine::a_format_immich_cannot_accept_is_never_an_item_or_a_failure
    — one refused .wma and one accepted .jpg: the .wma has no row, no
    attempt, no failed item, one upload request in total, and the folder detail
    count is 1.
  • Count persistence: a_later_scan_clears_the_count_once_the_refused_file_is_gone,
    store::the_unsupported_count_arrives_on_a_v13_database.
  • Old rows: a_scan_drops_rows_without_an_asset_for_a_format_the_allowlist_refuses
    (dropped with its attempt log; a row holding an asset kept).
  • Server-side 415: a_415_is_one_permanent_failure_and_is_never_retried now
    pins the readable reason.
  • UI: folder_detail::the_detail_names_the_files_immich_cannot_accept and the
    480 px window test assert the label; DashboardModel::from_engine keeps the
    global card at zero.
  • Gate on the rebased tree: cargo fmt --all -- --check,
    cargo clippy --workspace --all-targets -D warnings,
    cargo nextest run --workspace — 951 passed, 2 skipped.
  • Windows installer built from this branch (build-only release dispatch):
    https://github.com/elementalvoid/immich-sync/actions/runs/43374658579 —
    immich-sync_0.3.0_x64-setup.exe, sha256 a068f1ab…70ea7.

Merge Danger

Door: one-way for an install that has run this build — V14 adds
source_folder.unsupported (NOT NULL DEFAULT 0), and rolling the client back
after it opened a V14 database makes the older schema check refuse that
database. The migration itself is additive and safe to run forward.

Blast Radius: small — one new column, one count line in the folder detail,
and deletion of asset-less rows for formats the allowlist refuses.

The client now holds Immich's supported extensions in one allowlist, so a
file the server cannot accept is never queued: no state row, no attempt, no
dead letter. The scan counts the files it refused per folder, logs the count
and the extensions it saw, and the folder detail names them. A failed row
recorded before the allowlist existed is dropped by the next scan.
…ws (#95)

The review found the count field read like a flag, the scan's folder write
mixing two facts, and the cleanup deleting only failed rows. The count is now
unsupported_count, the count has its own store write, and every row without a
server asset is dropped, while a row that holds an asset keeps its mapping and
version chain. The startup requeue no longer sends a refused format.
@elementalvoid
elementalvoid merged commit be08ccf into main Nov 14, 2026
4 checks passed
@elementalvoid
elementalvoid deleted the ticket/95-supported-formats branch November 14, 2026 04:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Supported file formats

1 participant