fix: 3 correctness bugs from codebase audit round 2

- executor.py: clear min_quality_score_for_slot alongside effective_count
  restore in for/else block; leaving the stale floor from the deleted
  file's score blocked the next candidate from filling the restored slot
- cli.py: guard merge_ids with p.get('id') is not None, consistent with
  the _smaller_duplicate_ids fix; bare p['id'] raised KeyError on any
  person dict missing the id field in the auto-merge path
- immich_api.py: replace bare data['major'/'minor'/'patch'] subscripts
  with .get() in get_immich_version; KeyError was silently swallowed by
  except Exception, causing version-gated flags to disable without warning
This commit is contained in:
2026-06-17 01:54:13 +00:00
parent 5509be150e
commit eab3d9fe64
3 changed files with 10 additions and 2 deletions
+1 -1
View File
@@ -118,7 +118,7 @@ def _handle_duplicate_people(people: list[dict]) -> list[dict]:
for name, ps in sorted(duplicates.items()):
ordered = sorted(ps, key=lambda x: x.get("assetCount", 0), reverse=True)
survivor = ordered[0]
merge_ids = [p["id"] for p in ordered[1:]]
merge_ids = [p.get("id") for p in ordered[1:] if p.get("id") is not None]
rprint(
f" [cyan]Merging {name!r} inside Immich:[/cyan] keeping "
f"[dim]{survivor['id'][:8]}…[/dim] ({survivor.get('assetCount', 0)} assets), "
+4
View File
@@ -612,8 +612,12 @@ def upload_to_frigate(jobs: list[dict]) -> None:
# All retries exhausted without a successful upload.
# Restore the slot freed by the preceding delete so the next
# candidate still sees at_cap=True and must beat the replacement gate.
# Also clear the quality floor — the deleted file's score no longer
# represents any live Frigate file, and leaving it blocks the next
# candidate from filling the restored slot.
if at_cap:
effective_count += 1
min_quality_score_for_slot = None
progress.advance(upload_task)
+5 -1
View File
@@ -39,7 +39,11 @@ def get_immich_version() -> tuple[int, int, int] | None:
)
if resp.ok:
data = resp.json()
return (int(data["major"]), int(data["minor"]), int(data["patch"]))
major, minor, patch = data.get("major"), data.get("minor"), data.get("patch")
if major is None or minor is None or patch is None:
logger.debug("Unexpected Immich version schema: %s", data)
return None
return (int(major), int(minor), int(patch))
return None
except Exception:
return None