Frigate /api/faces response has person names as top-level keys with
lists of filenames — {person: [file, ...], "train": [...]}. The old
code incorrectly looked inside data["train"] as if it were a dict of
persons, causing 'list object has no attribute items' on every run.
Immich get_people() now checks for 401 before raise_for_status() and
logs a clear "API key invalid or expired" message instead of the raw
requests exception string.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bugs fixed (from high-effort review):
- InsightFace CPU fallback now passes providers=['CPUExecutionProvider'] and
wraps in _suppress_output() so broken GPU drivers don't cause fallback to
try the same broken provider again, and C-extension noise stays suppressed
- scheduler.py: BaseException → Exception (KeyboardInterrupt already re-raised;
winnow has no sys.exit() calls, so SystemExit would not occur, but Exception
is the correct scope)
- compose.yml: fix inverted AUTO_MODE comment (docker run -it enables
interactive mode via TTY, not non-interactive)
Model loading logging (embeddings.py):
- InsightFace: disk cache check, "not cached — downloading now (~300 MB)",
"loading into memory on GPU/CPU...", "ready on GPU/CPU (Xs)"
- SigLIP: same treatment; cache path derived dynamically from model_name
via HuggingFace slug convention (models--org--model) so it stays correct
if the model variant ever changes
Logging level audit (INFO/DEBUG/WARNING/ERROR):
- diversity.py: internal algo steps (clustering, medoids, adaptive threshold,
auto-stop decision) → DEBUG; final selection summaries stay INFO
- immich_api.py: "Fetching assets" and "Retained N assets" → DEBUG (callers
already print this to the console via rprint)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>