odysseus-dev/odysseus · error · HTTPException

Failed to list events

Error message

Failed to list events

What it means

Generic HTTP 500 from GET /events. After parsing the start/end range, the handler expands recurring events (rrule/EXDATE handling), sorts occurrences, and builds the response. Any exception in that pipeline — recurrence expansion errors, malformed stored rrule JSON, timezone data problems, or a DB failure — is logged as 'Failed to list events: <e>' and returned as this 500. Note malformed start/end parameters are deliberately caught earlier and return an empty list, so they do NOT cause this error.

Source

Thrown at routes/calendar_routes.py:1201

            events = q.order_by(CalendarEvent.dtstart).all()

            # Expand recurring events into individual occurrences.
            expanded = []
            for e in events:
                expanded.extend(_expand_rrule(e, start_dt, end_dt))

            # Sort by occurrence start time for consistent frontend ordering.
            truncated = any(e.get("truncated") for e in expanded)
            expanded.sort(key=lambda d: d["dtstart"])
            response: dict = {"events": expanded}
            if truncated:
                response["truncated"] = True
            return response
        except HTTPException:
            raise
        except Exception as e:
            logger.error("Failed to list events: %s", e)
            raise HTTPException(500, "Failed to list events")
        finally:
            db.close()

    @router.post("/events")
    async def create_event(request: Request, data: EventCreate):
        owner = _require_user(request)
        _reserve_calendar_uploads(request, data.color, data.description, data.location)
        db = SessionLocal()
        try:
            cal = None
            if data.calendar_href:
                cal = db.query(CalendarCal).filter(CalendarCal.id == data.calendar_href).first()
                # Reject calendars that aren't owned by the caller. The
                # previous `if cal and cal.owner and ...` check silently
                # passed null-owner (legacy) rows, letting any authenticated
                # user write events into them. Same null-owner gate as
                # `_get_or_404_calendar`.
                if cal and (cal.owner is None or cal.owner != owner):

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Inspect the server log ('Failed to list events: <e>') — it usually names the offending event uid or rrule.
  2. Query CalendarEvent rows for this owner and check rrule/recurrence_exdates for malformed values; fix or delete the bad row(s).
  3. Ensure timezone data is installed (tzdata package / system zoneinfo) if the error mentions a timezone lookup.
  4. Narrow the start/end window — if the error only appears for wide ranges, a far-future expansion overflow is the likely culprit.
Defensive patterns

Strategy: try-catch

Validate before calling

// sanity-check range before requesting
const s = new Date(start), e2 = new Date(end);
if (isNaN(s) || isNaN(e2) || s > e2) throw new RangeError('bad range');
await api.get(`/events?start=${s.toISOString()}&end=${e2.toISOString()}`);

Try / catch

try { await api.get('/events', {params: {start, end}}); }
catch (e) {
  if (e.status === 500) {
    // log contains the failing event/rrule; bisect the range to isolate it
    const half = midpoint(start, end);
    await Promise.all([fetchRange(start, half), fetchRange(half, end)]);
  } else throw e;
}

Prevention

When it happens

Trigger: A stored event whose rrule or recurrence_exdates column holds malformed JSON or an impossible RRULE (e.g. COUNT=0, bogus FREQ) making the expansion engine throw; missing pytz/zoneinfo data for a stored timezone; database failure mid-query; a datetime overflow during expansion of a far-future recurring event.

Common situations: An event imported from a quirky ICS file left a nonstandard RRULE in the DB; a client wrote a DTSTART with an IANA timezone the runtime cannot resolve; DST edge in a timezone during expansion; an EXDATE that does not match any occurrence causing downstream code to fail.

Related errors


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