Skip to content

fix(calendar): resolve Microsoft series masters through their calendar - #1835

Merged
Chadpiha merged 1 commit into
mainfrom
fix/microsoft-shared-calendar-backfill
Aug 25, 2026
Merged

fix(calendar): resolve Microsoft series masters through their calendar#1835
Chadpiha merged 1 commit into
mainfrom
fix/microsoft-shared-calendar-backfill

Conversation

@Chadpiha

Copy link
Copy Markdown
Collaborator

What & why

Customer report (v1.9.0): recurring Microsoft Calendar meetings render as "Untitled Event"
in Upcoming Meetings while one-off meetings sync fine.

Graph's calendarView/delta returns recurring-series occurrences as bare
{ id, type, seriesMasterId, start, end } stubs. #1665 backfills them from their series
master via GET /me/events/{id} — but that path only resolves items in the user's own
mailbox
. For events on a shared calendar it 404s on every sync, so every recurring meeting
there is stored with a NULL summary, permanently. Two compounding gaps kept even transient
failures visible: incremental delta never re-delivers an unchanged occurrence, and a failed
backfill was never retried, so a bare stub stuck as an untitled block until the 7-day delta
token expiry.

Three changes, each covered test-first:

  1. Calendar-scoped master fetch/me/calendars/{calendarId}/events/{id}. A series
    master always lives in the same calendar as its occurrences, so the scoped path works for
    own and shared calendars alike.
  2. Backfill retry — when any occurrence is still stripped after backfill, the delta token
    TTL is capped at 10 minutes, so an early full sync retries the master fetch instead of
    leaving untitled blocks for up to a week.
  3. One-time heal migration (user_version 2) — clears stored Microsoft sync tokens so the
    first launch on this build runs a full sync and re-fetches rows that earlier builds stored
    untitled. Without it, a still-fresh delta token would keep pre-fix untitled rows on screen
    for up to 7 more days after updating.

Testing

  • Full suite: 2981 tests, 0 failures (177 skips are the known better-sqlite3 ABI skips; the
    9 calendarDatabase tests, including the new migration test, were additionally run locally
    under ELECTRON_RUN_AS_NODE against the Electron binary — 9/9 pass)
  • All three behavior changes were watched fail red before implementation

Follow-ups / limitations

  • Wants a 1.9.1 patch release — the customer-visible fix only lands with the migration
    (remember the NEXT_PUBLIC_RELEASE_VERSION bump on the website after publishing)
  • _apiGet still has no Retry-After handling for Graph 429s; the shortened-TTL retry
    bounds the damage (untitled for minutes, not days) but a throttled initial sync isn't
    retried within the same sync pass
  • Free/busy-only shared calendars are unaffected: Graph genuinely returns "Busy" as the
    subject there, which is correct behavior, not this bug

Graph's calendarView/delta returns recurring occurrences as bare stubs
that are backfilled from their series master. That fetch used
GET /me/events/{id}, which only resolves items in the user's own
mailbox — masters on shared calendars 404 there, so every recurring
meeting on a shared calendar rendered as an untitled time block.

- Fetch masters via /me/calendars/{calendarId}/events/{id}; a master
  always lives in the same calendar as its occurrences, so the scoped
  path works for own and shared calendars alike
- Cap the delta token TTL at 10 minutes when a master fetch fails, so
  an early full sync retries the backfill instead of leaving bare
  stubs untitled until the 7-day expiry (delta never re-delivers
  unchanged occurrences)
- One-time migration (user_version 2) clears stored Microsoft sync
  tokens so rows written untitled by earlier builds heal on the first
  sync after updating
@Chadpiha
Chadpiha force-pushed the fix/microsoft-shared-calendar-backfill branch from 84dfc39 to c3f3219 Compare August 25, 2026 19:18
@Chadpiha
Chadpiha merged commit a0bbf4f into main Aug 25, 2026
9 checks passed
github-actions Bot pushed a commit to PlaybookMediaLLC/openwhispr that referenced this pull request Aug 26, 2026
# [1.11.0](v1.10.0...v1.11.0) (2026-08-26)

### Bug Fixes

* **ai:** retry HTTP 408 request timeouts in the API retry strategy ([OpenWhispr#1734](https://github.com/PlaybookMediaLLC/openwhispr/issues/1734)) ([d3661cb](d3661cb))
* **auth:** Unify onboarding and reauthentication display ([OpenWhispr#1763](https://github.com/PlaybookMediaLLC/openwhispr/issues/1763)) ([3cc197f](3cc197f))
* **calendar:** fail OAuth loopback immediately on state mismatch ([OpenWhispr#1753](https://github.com/PlaybookMediaLLC/openwhispr/issues/1753)) ([8b77a59](8b77a59))
* **calendar:** group date-only upcoming events on the local calendar day ([2ef397b](2ef397b))
* **calendar:** resolve Microsoft series masters through their calendar ([OpenWhispr#1835](https://github.com/PlaybookMediaLLC/openwhispr/issues/1835)) ([a0bbf4f](a0bbf4f))
* **chat:** persist conversation migration links ([OpenWhispr#1772](https://github.com/PlaybookMediaLLC/openwhispr/issues/1772)) ([15b5b3f](15b5b3f))
* click should be the delibrate action to select model for STT models ([90cfe03](90cfe03))
* **cli:** enforce request body byte limit ([OpenWhispr#1777](https://github.com/PlaybookMediaLLC/openwhispr/issues/1777)) ([996fe79](996fe79))
* **cli:** preserve UTF-8 request bodies ([OpenWhispr#1386](https://github.com/PlaybookMediaLLC/openwhispr/issues/1386)) ([ef627c9](ef627c9))
* **diarization:** diarize the mic track for in-person meetings — fixes [OpenWhispr#1627](https://github.com/PlaybookMediaLLC/openwhispr/issues/1627) ([0a10184](0a10184))
* **diarization:** skip orphan speaker embeddings in softened mic mode ([2ffbe35](2ffbe35))
* **dictation:** initialize onboarding event ref safely ([OpenWhispr#1756](https://github.com/PlaybookMediaLLC/openwhispr/issues/1756)) ([c5d515b](c5d515b))
* dismiss dictation preview when no audio detected ([OpenWhispr#1667](https://github.com/PlaybookMediaLLC/openwhispr/issues/1667)) ([7208bdf](7208bdf))
* **history:** keep the wide two-column layout regardless of calendar connection ([d45d1d2](d45d1d2))
* **i18n:** guard localStorage deref against partial window stubs ([OpenWhispr#1842](https://github.com/PlaybookMediaLLC/openwhispr/issues/1842)) ([0686a26](0686a26))
* **linux:** map KDE punctuation hotkeys to Qt key codes ([OpenWhispr#1752](https://github.com/PlaybookMediaLLC/openwhispr/issues/1752)) ([523acab](523acab))
* **linux:** Preserve focus for Sway overlays ([OpenWhispr#1718](https://github.com/PlaybookMediaLLC/openwhispr/issues/1718)) ([063b5b6](063b5b6))
* **linux:** push-to-talk on Wayland (Hyprland, KDE, GNOME 48+) for dictation hotkey ([OpenWhispr#1738](https://github.com/PlaybookMediaLLC/openwhispr/issues/1738)) ([b5c5fb4](b5c5fb4))
* **local-llm:** Phase 0 correctness + hygiene fixes for local model params and canaries ([OpenWhispr#1714](https://github.com/PlaybookMediaLLC/openwhispr/issues/1714)) ([41cf1d4](41cf1d4)), closes [OpenWhispr#1176](https://github.com/PlaybookMediaLLC/openwhispr/issues/1176) [OpenWhispr#1021](https://github.com/PlaybookMediaLLC/openwhispr/issues/1021) [OpenWhispr#1611](https://github.com/PlaybookMediaLLC/openwhispr/issues/1611)
* **logging:** Suppress packaged Windows console output ([OpenWhispr#1719](https://github.com/PlaybookMediaLLC/openwhispr/issues/1719)) ([30dedcf](30dedcf))
* make model selection an explicit click and only bootstrap if no model is selected/downloaed ([b9b5335](b9b5335))
* **meeting:** handle nullish segments and non-object patches in speakerAssignmentPolicy ([OpenWhispr#1798](https://github.com/PlaybookMediaLLC/openwhispr/issues/1798)) ([c519e1f](c519e1f)), closes [OpenWhispr#1797](https://github.com/PlaybookMediaLLC/openwhispr/issues/1797)
* Mode-switch validity guard ([58d9af0](58d9af0))
* **models:** Honor redirected cache roots ([OpenWhispr#1721](https://github.com/PlaybookMediaLLC/openwhispr/issues/1721)) ([da39195](da39195)), closes [OpenWhispr#1279](https://github.com/PlaybookMediaLLC/openwhispr/issues/1279)
* **network:** treat the full IPv6 link-local range as private HTTP ([OpenWhispr#1733](https://github.com/PlaybookMediaLLC/openwhispr/issues/1733)) ([1fe91f2](1fe91f2))
* **notes:** abort local transcription and diarization when an upload is cancelled — fixes [OpenWhispr#1401](https://github.com/PlaybookMediaLLC/openwhispr/issues/1401) ([7bbc04c](7bbc04c))
* **notes:** format future timestamps as dates ([OpenWhispr#1768](https://github.com/PlaybookMediaLLC/openwhispr/issues/1768)) ([5d5f08c](5d5f08c))
* **notes:** keep markdown mirror paths inside base ([OpenWhispr#1773](https://github.com/PlaybookMediaLLC/openwhispr/issues/1773)) ([2893be4](2893be4))
* **notes:** keep note content visible above the floating chat panel ([OpenWhispr#1769](https://github.com/PlaybookMediaLLC/openwhispr/issues/1769)) ([fa11ddc](fa11ddc))
* **notes:** reject cancelled uploads before ffmpeg conversion and server boot ([53ec075](53ec075))
* **parakeet:** Clarify unsupported-macOS guidance and dedupe version compare ([cd4dedc](cd4dedc)), closes [OpenWhispr#862](https://github.com/PlaybookMediaLLC/openwhispr/issues/862) [OpenWhispr#764](https://github.com/PlaybookMediaLLC/openwhispr/issues/764) [OpenWhispr#862](https://github.com/PlaybookMediaLLC/openwhispr/issues/862)
* **parakeet:** Gate incompatible macOS runtime ([0c271fe](0c271fe)), closes [OpenWhispr#862](https://github.com/PlaybookMediaLLC/openwhispr/issues/862)
* **parakeet:** Localize disabled provider tab labels ([514866c](514866c)), closes [OpenWhispr#862](https://github.com/PlaybookMediaLLC/openwhispr/issues/862)
* **paste:** skip trailing space after CJK text in append smart spacing ([OpenWhispr#1823](https://github.com/PlaybookMediaLLC/openwhispr/issues/1823)) ([f26b059](f26b059))
* retire dead cloud models and make the canary suites trustworthy ([OpenWhispr#1722](https://github.com/PlaybookMediaLLC/openwhispr/issues/1722)) ([9b3f57a](9b3f57a))
* **settings:** Clamp the LLM request timeout input on blur ([7032088](7032088))
* **settings:** close stale-state gaps in explicit model selection ([82fd37a](82fd37a))
* **settings:** enforce auto-end and request timeout defaults ([OpenWhispr#1755](https://github.com/PlaybookMediaLLC/openwhispr/issues/1755)) ([77c6661](77c6661))
* **settings:** harden browse-only provider tabs and drop dead code ([983bf58](983bf58))
* **settings:** keep the browsed whisper-list validation off foreign local models ([204e83b](204e83b))
* **snippets:** do not crash snippet expansion when the list is nullish ([773fed0](773fed0))
* **stores:** Survive imports under partial browser window stubs ([OpenWhispr#1841](https://github.com/PlaybookMediaLLC/openwhispr/issues/1841)) ([b934b88](b934b88))
* **uploads:** anchor upload transcript timestamps to the meeting path's epoch-ms base ([df826f0](df826f0))
* **uploads:** normalize provider names and clamp verbose segment timestamps ([OpenWhispr#1800](https://github.com/PlaybookMediaLLC/openwhispr/issues/1800)) ([d9499f5](d9499f5)), closes [OpenWhispr#1799](https://github.com/PlaybookMediaLLC/openwhispr/issues/1799)
* **utils:** handle nullish and invalid inputs safely in date formatting ([OpenWhispr#1783](https://github.com/PlaybookMediaLLC/openwhispr/issues/1783)) ([OpenWhispr#1784](https://github.com/PlaybookMediaLLC/openwhispr/issues/1784)) ([858e824](858e824))
* validate transcription hosts exactly ([8aced79](8aced79))
* **whisper:** accept any casing for the GPU opt-out flag ([28bf6f4](28bf6f4))
* **whisper:** engage downloaded GPU packs without the env flag ([d4c207a](d4c207a)), closes [OpenWhispr#1340](https://github.com/PlaybookMediaLLC/openwhispr/issues/1340)
* **whisper:** raise decoder anti-hallucination thresholds on local transcription — fixes [OpenWhispr#1458](https://github.com/PlaybookMediaLLC/openwhispr/issues/1458) ([b7fdf80](b7fdf80))
* **windows:** block untrusted file navigation ([OpenWhispr#1776](https://github.com/PlaybookMediaLLC/openwhispr/issues/1776)) ([45c20b8](45c20b8))
* **windows:** restore the captured target window before pasting — fixes [OpenWhispr#859](https://github.com/PlaybookMediaLLC/openwhispr/issues/859) ([de9e335](de9e335)), closes [OpenWhispr#668](https://github.com/PlaybookMediaLLC/openwhispr/issues/668)

### Features

* **billing:** self-serve Enterprise upgrade + admin console entry ([OpenWhispr#1623](https://github.com/PlaybookMediaLLC/openwhispr/issues/1623)) ([e039861](e039861))
* **calendar:** add provider-neutral availability tool ([OpenWhispr#1821](https://github.com/PlaybookMediaLLC/openwhispr/issues/1821)) ([b96f4a2](b96f4a2))
* **calendar:** redesign Coming up sidebar with join-and-take-notes and empty states ([a5e59ee](a5e59ee))
* complete Oppulence Voice cloud integration ([fed389c](fed389c))
* **hyprland:** support both Lua and legacy configs ([OpenWhispr#1664](https://github.com/PlaybookMediaLLC/openwhispr/issues/1664)) ([47da21d](47da21d))
* **llm:** Apply the configurable request timeout to the Tinfoil provider ([f240775](f240775)), closes [OpenWhispr#1479](https://github.com/PlaybookMediaLLC/openwhispr/issues/1479)
* **meetings:** Auto-end forgotten meeting recordings ([OpenWhispr#1494](https://github.com/PlaybookMediaLLC/openwhispr/issues/1494)) ([bc306d2](bc306d2))
* **models:** add Gemini 3.5 and 3.1 Flash Lite models ([OpenWhispr#1702](https://github.com/PlaybookMediaLLC/openwhispr/issues/1702)) ([90f79b6](90f79b6))
* **notes:** real speaker identity in note generation and [@mention](https://github.com/mention) owner tagging ([672cc90](672cc90))
* **onboarding:** rebuild guided setup experience ([OpenWhispr#1670](https://github.com/PlaybookMediaLLC/openwhispr/issues/1670)) ([9382171](9382171)), closes [#141414](https://github.com/PlaybookMediaLLC/openwhispr/issues/141414)
* **policy:** Enforce org-required local model downloads ([OpenWhispr#1836](https://github.com/PlaybookMediaLLC/openwhispr/issues/1836)) ([409bc28](409bc28))
* **policy:** Mirror the server-only memoryEnabled org-policy field ([OpenWhispr#1717](https://github.com/PlaybookMediaLLC/openwhispr/issues/1717)) ([91c1195](91c1195))
* **sidebar:** redesign Upgrade to Pro banner to new card style ([973cbf5](973cbf5))
* **uploads:** persist segment timestamps from BYOK cloud transcriptions for SRT export — fixes [OpenWhispr#1095](https://github.com/PlaybookMediaLLC/openwhispr/issues/1095) ([aada021](aada021))

### Performance Improvements

* **windows:** skip the paste settle when the target is already foreground ([0266639](0266639))
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.

1 participant