Notes from the widget version graveyard
Two consecutive widget versions shipped a broken IIFE bundle. Here is what we did about it, and what we changed so it cannot happen again.
In late March, we shipped two consecutive widget versions (1.2.20 and 1.2.21) with the same bug: the IIFE bundle externalised ofetch and its workspace siblings, expecting them to be resolvable at runtime. They were not. Every site that pinned to those versions logged a ReferenceError on first interaction.
This post is the post-mortem, with the names left in. Pretending it did not happen would be worse than writing it down.
What broke
@reqdesk/widget ships an IIFE bundle for embedded use. The bundler treated the workspace siblings (@reqdesk/sdk-core, @reqdesk/sdk-react) and ofetch as external — which is correct for the ESM build (consumers install them as deps) but wrong for the IIFE build (consumers want a single self-contained file).
A test would have caught this. We did not have one for the IIFE bundle. We do now.
What we did about it
- Pulled both versions from the CDN retention list immediately. Sites pinned to 1.2.20 / 1.2.21 now 404 instead of silently 500-ing. A 404 fails fast and obvious; a runtime ReferenceError fails slowly and quietly. We will take the 404.
- Shipped 1.2.22 with the IIFE bundle properly inlining
ofetchand the workspace siblings. - Bumped the Filament plugin’s
script_url_defaultto 1.2.22 and tagged a plugin release. - Added a Vitest spec that loads the IIFE bundle in a JSDOM environment and asserts the widget renders without throwing. The spec runs in CI on every widget change.
What we changed about the runbook
The CDN runbook in CLAUDE.md now has an explicit “do NOT retain known-broken versions” rule. The comment block at the top of retained-versions.txt is the canonical record of why each excluded version is excluded. Future-us will not be confused.
Why a 404 beats a silent break
Because broken JavaScript on a customer’s site is invisible to us. The customer sees their support widget never appear, assumes the integration is fragile, and quietly removes it. A 404 in DevTools is at least findable. We chose visibly-broken over invisibly-broken — and we will keep choosing it.