odysseus-dev/odysseus · critical · HTTPException

Failed to fetch gallery library

Error message

Failed to fetch gallery library

What it means

HTTP 500 raised by GET of the gallery library endpoint when the broad try/except around the query/aggregation block catches any exception. The handler logs 'Failed to fetch gallery library' with a full traceback and re-raises as a generic 500. Because the except is untyped, causes range from SQL errors to failures inside _image_to_dict.

Source

Thrown at routes/gallery/gallery_routes.py:806

                    q = q.order_by(GalleryImage.created_at.asc())
                else:  # recent
                    q = q.order_by(GalleryImage.created_at.desc())
                rows = q.offset(offset).limit(limit).all()

            items = []
            for img, session_name in rows:
                items.append(_image_to_dict(img, session_name))

            return {
                "items": items,
                "total": total,
                "total_tagged": total_tagged,
                "tags": sorted(all_tags),
                "models": all_models,
            }
        except Exception:
            logger.exception("Failed to fetch gallery library")
            raise HTTPException(500, "Failed to fetch gallery library")
        finally:
            db.close()

    # ---- Album CRUD (must be before {image_id} catch-all) ----

    @router.get("/api/gallery/albums")
    async def list_albums(request: Request):
        user = get_current_user(request)
        db = SessionLocal()
        try:
            q = db.query(GalleryAlbum)
            q = _owner_filter(q, user, GalleryAlbum)
            albums = q.order_by(GalleryAlbum.created_at.desc()).all()
            result = []
            for a in albums:
                _count_q = db.query(GalleryImage).filter(
                    GalleryImage.album_id == a.id, GalleryImage.is_active == True
                )

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Read the server log — the logger.exception traceback names the actual failing operation.
  2. If it is schema drift, run the project's migrations so GalleryImage/DbSession columns match the ORM.
  3. If it is a bad row, identify and repair/delete it based on the traceback.
  4. Restart after DB maintenance; retry once the connection is stable.
Defensive patterns

Strategy: retry

Try / catch

try { return await fetchLibrary(); }
catch (e) {
  if (e.status !== 500) throw e;
  await sleep(1000);
  return await fetchLibrary(); // single retry for transient DB issues
}

Prevention

When it happens

Trigger: Schema drift (columns like tags/models missing after an upgrade without migration), a corrupted row that breaks _image_to_dict, DB connection loss, or an aggregation query failing on unexpected NULLs.

Common situations: Upgrading the app without running migrations; SQLite file locked by a backup job; a row with NULL in a field the serializer assumes is present.

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/7b41e1ef1bb8ec6c. Report an issue: GitHub.