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
- Inspect the server log ('Failed to list events: <e>') — it usually names the offending event uid or rrule.
- Query CalendarEvent rows for this owner and check rrule/recurrence_exdates for malformed values; fix or delete the bad row(s).
- Ensure timezone data is installed (tzdata package / system zoneinfo) if the error mentions a timezone lookup.
- 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
- Always send ISO 8601 start/end parameters; malformed ones silently return an empty list instead of an error, which hides data.
- If 500s appear, narrow the date window to identify the corrupt recurring event, then fix or delete it.
- Validate imported RRULEs before persisting them to keep malformed recurrence data out of the DB.
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
- Failed to delete calendar
- Failed to list calendars
- Failed to create event
- Failed to update event
- Invalid recurring occurrence uid
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/be6ea05878a0515e.
Report an issue: GitHub.