Skip to content

fix: past due meetings are now 8h for ics#958

Merged
yamijuan merged 1 commit intomainfrom
juan/bug
Apr 24, 2026
Merged

fix: past due meetings are now 8h for ics#958
yamijuan merged 1 commit intomainfrom
juan/bug

Conversation

@yamijuan
Copy link
Copy Markdown
Contributor

Description

Fixes two related issues that caused users to fail to rejoin ICS-scheduled meetings after a network drop:

  1. ICS-pre-created meetings now use an 8-hour rejoin window anchored to the scheduled start, matching manual on-the-fly meetings. Previously the meeting's end_date was copied straight from the calendar event's DTEND, so a 30-minute scheduled block turned into a 30-minute hard cap on rejoining even when participants were still in the call.
  2. Join-error messaging surfaces the real backend detail ("Meeting has ended", "Meeting is not active", etc.) via a new formatJoinError helper in errorUtils.ts, wired into DailyRoom, LiveKitRoom, and MeetingSelection. The generic global toast in useRoomJoinMeeting was dropped in favor of colocated, specific messages.

The calendar event's original DTEND is still preserved in calendar_events.end_time for reference — only the derived meetings.end_date changed.

Motivation and Context

A client was in a Daily.co meeting scheduled via ICS for 19:00–19:30 UTC on room=<z>. Participants ran over the scheduled window. At 19:39 the client's internet dropped; when they came back at 19:40 they got 400 "Meeting has ended" on POST /v1/rooms/<z>/meetings/xxxxxx-.../join (frontend flattened this to the generic "Failed to join meeting. Please try again."). The other two participants, whose Daily WebRTC sockets never disconnected, stayed in the call — so from the client's perspective the room page said "no active meetings" while their colleagues were visibly still talking.

Root cause traced to server/reflector/worker/ics_sync.py:105:

end_date = event.end_time or (event.start_time + MEETING_DEFAULT_DURATION)

vs. manual meetings at rooms.py:346 which use current_time + timedelta(hours=8). The join endpoint at rooms.py:582-583 enforces end_date as a hard boundary for new joins, but Daily doesn't enforce it for existing connections — creating the asymmetric failure.

Server DB snapshot for the incident confirms:

start_date        = 2026-04-23 19:00:00+00
end_date          = 2026-04-23 19:30:00+00
calendar_event_id = 2d29c1e9-55ba-4c86-863e-0fe555820973   (ICS-sourced)

How Has This Been Tested?

Automated

Added regression test test_create_upcoming_meeting_uses_8h_end_date in server/tests/test_ics_background_tasks.py — builds an ICS-linked calendar event with a 30-minute DTEND, mocks the platform client, calls create_upcoming_meetings_for_event, and asserts meeting.end_date == event.start_time + 8h.

REDIS_HOST=localhost REDIS_PORT=6379 uv run pytest tests/test_ics_background_tasks.py tests/test_multiple_active_meetings.py -v
======================= 10 passed, 15 warnings in 18.20s =======================

Frontend:

pnpm typecheck   # tsc --noEmit — clean

(pnpm lint is pre-existing broken — next lint deprecated in Next 15; not touched in this PR.)

Manual

  1. 8h ICS window, end-to-end: created an ICS event with LOCATION: https://<UI_BASE_URL>/<test_room>, 15-min DTSTART/DTEND starting in ~5 min. Let sync_room_ics + create_upcoming_meetings beat tasks run. Confirmed in DB:

    SELECT end_date - start_date AS duration FROM meetings WHERE calendar_event_id IS NOT NULL ORDER BY created_at DESC LIMIT 1;
    -- duration = 08:00:00

    Joined the meeting, stayed past the 15-min ICS window, disconnected one client, rejoined via the meeting link — got 200 OK with a fresh Daily token (previously this returned 400 "Meeting has ended").

  2. Error messaging per branch, forcing each backend condition:

    UPDATE meetings SET end_date = NOW() - INTERVAL '10 minutes' WHERE id = '<id>';

    → navigating to /<room>/<id> rendered "This meeting has ended. The organizer can start a new one."

    UPDATE meetings SET is_active = false WHERE id = '<id>';

    → rendered "This meeting is no longer active. Ask the organizer to start it again."

@yamijuan yamijuan requested a review from tito April 23, 2026 22:34
@yamijuan yamijuan merged commit 52888f6 into main Apr 24, 2026
7 checks passed
@yamijuan yamijuan deleted the juan/bug branch April 24, 2026 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants