fix(clip): stop re-sending undecodable files every pass

A 422 from Apollo's /encode_image (bytes it can't decode — corrupt
files, non-images with an image extension) left clip_embedding NULL,
so the drain re-sent the file and logged the same "permanent failure
(will retry next pass)" on every scan.

Permanent rejections now record a clip_failures marker scoped to the
row's content_hash; list_clip_unencoded_candidates skips the row while
the hash still matches, so a replaced file gets another try with no
cleanup. Only 422 (new ClipError::Rejected) marks: other 4xx are
deployment problems (auth, routing) and would otherwise blacklist the
whole library.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Cameron CordesandClaude Opus 5.5 committed 2026-10-17 00:20:00 -04:00
1 parent a605ccd6f8
commit e75e60786d
9 files changed
+179 -25

No files matched your search

+12
View File
@@ -18,6 +18,16 @@ diesel::table! {
}
}
diesel::table! {
clip_failures (library_id, rel_path) {
library_id -> Integer,
rel_path -> Text,
content_hash -> Text,
error -> Text,
failed_at -> BigInt,
}
}
diesel::table! {
daily_conversation_summaries (id) {
id -> Integer,
@@ -348,6 +358,7 @@ diesel::table! {
diesel::joinable!(entity_facts -> photo_insights (source_insight_id));
diesel::joinable!(entity_photo_links -> entities (entity_id));
diesel::joinable!(entity_photo_links -> libraries (library_id));
diesel::joinable!(clip_failures -> libraries (library_id));
diesel::joinable!(face_detections -> libraries (library_id));
diesel::joinable!(face_detections -> persons (person_id));
diesel::joinable!(image_exif -> libraries (library_id));
@@ -360,6 +371,7 @@ diesel::joinable!(video_preview_clips -> libraries (library_id));
diesel::allow_tables_to_appear_in_same_query!(
calendar_events,
clip_failures,
daily_conversation_summaries,
entities,
entity_facts,