odysseus-dev/odysseus · warning · HTTPException

Unknown wipe kind: {kind!r}

Error message

Unknown wipe kind: {kind!r}

What it means

HTTPException(400) from the admin wipe endpoint: the 'kind' path/query value did not match any of the handled wipe branches (the if-chain covering gallery, calendar, etc.) and execution fell through to the explicit unknown-kind guard.

Source

Thrown at routes/admin_wipe/admin_wipe_routes.py:166

            if kind == "gallery":
                count = db.query(GalleryImage).count() + db.query(GalleryAlbum).count()
                db.query(GalleryImage).delete()
                db.query(GalleryAlbum).delete()
                db.commit()
                # Also drop the upload dir so disk doesn't keep orphans.
                _rmtree_quiet(GALLERY_DIR)
                _rmtree_quiet(GALLERY_UPLOADS_DIR)
                return {"status": "deleted", "kind": kind, "count": count}

            if kind == "calendar":
                # Events FK calendars — clear children first, then both.
                db.query(CalendarEvent).delete()
                count = db.query(CalendarCal).count()
                db.query(CalendarCal).delete()
                db.commit()
                return {"status": "deleted", "kind": kind, "count": count}

            raise HTTPException(400, f"Unknown wipe kind: {kind!r}")
        except HTTPException:
            raise
        except Exception as e:
            db.rollback()
            logger.exception(f"Wipe {kind} failed")
            raise HTTPException(500, f"Wipe {kind} failed: {e}")
        finally:
            db.close()

    return router

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Use the exact kind strings implemented in the route's if-chain (read admin_wipe_routes.py)
  2. Check the API docs/OpenAPI schema for the wipe endpoint's accepted values
  3. If a new kind should be wipeable, add an explicit branch rather than guessing

Example fix

# before
curl -X POST /api/admin/wipe?kind=calendars
# after
curl -X POST /api/admin/wipe?kind=calendar
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED = {'gallery','calendar', ...}  # mirror the route's if-chain
if kind not in SUPPORTED:
    raise ValueError(f'kind must be one of {sorted(SUPPORTED)}')

Type guard

def is_supported_wipe_kind(kind: str) -> bool:
    return kind in {'gallery','calendar'}  # keep in sync with route

Try / catch

try:
    client.post(f'/api/admin/wipe?kind={kind}')
except HTTPError as e:
    if e.response.status_code == 400 and 'Unknown wipe kind' in e.response.text:
        raise ValueError(f'bad kind: {kind}') from e
    raise

Prevention

When it happens

Trigger: POST/DELETE to the wipe endpoint with kind=typo (e.g. 'galery'), a plural form ('calendars'), or a kind that exists in the app but has no wipe branch (e.g. 'tokens').

Common situations: Guessing endpoint payloads without reading the route; versions where supported kinds changed; shell quoting dropping or mangling the kind value.

Related errors


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