Fullstory
Marriott International
Digital Experience Analysis — September 2026

46,136 Users Can't Book
with Their Points

A race condition in Marriott.com's Next.js booking SPA causes a redemptionNotAvailableError to fire before the rewards availability API has resolved — blocking every affected user from completing a points redemption booking. Fullstory session analysis across 23 sessions and 30 days of segment data confirms 100% error rate and 0% booking completion for affected users.

⚠ 100% error rate — 23/23 sessions 8.5 avg Rate List visits before abandon Race condition — fixable at source

A timing bug blocks every user who tries to redeem Bonvoy points online.

When a Bonvoy member (or guest) selects a hotel from search results and lands on the Rate List Menu, the booking SPA fires a client-side validation check before the rewards availability API response arrives. The error fires twice simultaneously — a signature of two concurrent validation passes — and replaces the entire points interface with an error state from which most users cannot recover.

This isn't a data issue, an authentication issue, or a property configuration issue. It affects Guests and Platinum Premier Lifetime Elite members equally, across 10 loyalty tiers, on every platform, in every locale studied. The bug is in the timing of the validation layer relative to the async API call.

46,136 users encountered this in the last 30 days. Zero of the 23 sessions studied resulted in a points booking. 87% of affected users abandoned entirely. The remaining 13% either switched to cash rates or continued searching in a frustration loop — with one user visiting the Rate List page 37 times in a single session.

The problem is larger than it looks

An expert-built Fullstory segment — constructed by searching for users who visited the hotel search results page and subsequently encountered the #RedemptionError UI element in order, within the same session — captures the true exposure footprint.

Segment: "Rewards Search Follow by Redemption Error" — built by irv@fullstory.com. Criteria: users who visited SERP (hotel search), then saw the #RedemptionError element, in-session sequence, last 30 days.
46,136
Affected users (30 days)
Encountered redemption error after reaching Rate List Menu
51,159
Affected sessions (30 days)
Some users hit the error in multiple separate sessions
0%
Points booking completion
23/23 sessions reviewed — zero resulted in a points booking
8.5×
Avg Rate List page visits
Per session before abandonment — peak: 37 visits (1 user)
Note on undercount: This segment captures confirmed cases — users who made it to SERP, clicked through to RLM, and had #RedemptionError tracked. Users who abandoned at SERP without clicking through, or whose sessions were not fully captured, are not included. True exposure is likely higher.

A race condition, not a data problem

The booking SPA runs client-side validation on page mount — before the async rewards availability API has had time to respond. This is the core defect. Authentication status, loyalty tier, travel dates, and property configuration are all irrelevant to whether the error fires.

Definitive signal: The console error fires exactly twice simultaneously in every affected session — a signature of two concurrent validation passes executing in parallel. If the error were data-driven (e.g., rewards actually not available), it would fire once, and it would vary by property and date. It doesn't.
Execution Timeline — What Fires on RLM Page Mount
Timeline
Event
t+0ms
Page mount — RLM SPA initializes, component tree hydrates
t+~5ms
⚡ Validation pass #1 fires — rewards API result: not yet available
t+~5ms
⚡ Validation pass #2 fires simultaneously — same empty state, same result
t+~5ms
#RedemptionError rendered — UI locked into error state for this session
t+200–800ms
✓ Rewards availability API resolves — result: rewards are available
t+200–800ms
API result ignored — error state already committed to DOM
// Console log captured in every affected session (fires ×2 simultaneously) Client Side Validation Error, Page State: {"pageLevelErrors":{"redemptionNotAvailableE... // (Fullstory log captures first ~80 chars; full key is "redemptionNotAvailableError")
// Secondary JS error fires when user attempts to click "Select" post-error (11 sessions): ReferenceError: Can't find variable: s // Occurs even on the rare occasions when the redemption error UI resolves itself
Why property-specific behavior doesn't contradict this: In some sessions, a user visited 7 different hotels and only 2 triggered the error. This is consistent with a race condition — faster API responses on some properties (lower server load, cached data, simpler inventory) resolve before validation fires. The race is only lost when API latency exceeds the validation window, which varies by property and time-of-day.

23 sessions reviewed in full

Every session in the expert segment was reviewed systematically using Fullstory's session event stream. Sessions were drawn across loyalty tiers, platforms, geographies, and session dates to ensure breadth of coverage. All 23 confirmed the same error pattern.

Methodology: Session event data was extracted via Fullstory MCP get_session_events for each session. Key signals extracted per session: loyalty tier (mr_prof_rewards_level), error presence (redemptionNotAvailableE... in console), #RedemptionError element render, Rate List Menu visit count, booking confirmation page presence. Python analysis applied across all 23 sessions.

Session Group A — Guest & Basic Members

10 sessions
Error rate100%
Booking completion0%
Avg RLM visits7.2×
PlatformsiOS, Android, Windows, Linux
NoteGuest users hit same error as members

Session Group B — Silver & Gold Members

4 sessions
Error rate100%
Booking completion4.3% (1 via hidden button)
Avg RLM visits9.5×
Notable1 Silver member found hidden "View Rates" escape button
Cash rate switch1 user switched to non-points rate

Session Group C — Platinum & Platinum Achiever

4 sessions
Error rate100%
Booking completion0%
Avg RLM visits8.3×
NotablePlatinum Achiever: 20 RLM visits before abandonment
PlatformsmacOS, Windows Chrome/Edge

Session Group D — Platinum Premier & Lifetime Elite

5 sessions
Error rate100%
Booking completion0%
Avg RLM visits15.4×
Peak frustration37 RLM visits (Platinum Lifetime Elite, Rancho Cordova)
NoteHighest-tier users exhibit longest frustration loops
Session Identifier Tier Platform RLM Visits Outcome
iOS / TerryvilleGuestiOS Safari5Abandoned
Linux / San JoseGuestLinux Chrome6Abandoned
OSX / Mount HealthyGuestmacOS Safari4Abandoned
Win / HaverstrawPlatinum AchieverWindows Chrome9Abandoned
OSX / hskeelsGoldmacOS Chrome20Abandoned
OSX / Rancho CordovaPlatinum Lifetime ElitemacOS Chrome37Abandoned
DC / jdmanPlatinum AchieverWindows Edge7Abandoned
Santa Monica / jennaSilvermacOS Safari3Switched to cash
iOS / TempeGoldiOS Safari6Abandoned
Highland CityPlatinum Premier AchieverWindows Chrome6Abandoned
DallasGuestWindows Chrome7Abandoned
Enfield / cindijamesPlatinum Premier AchievermacOS Chrome7Abandoned
en-gb (London)GuestmacOS Safari5 hotels, 5 date combosSwitched hotel, hit JS error
/ja/ (Japan)GuestiOS Safari4Abandoned
+ 9 additional sessionsVarious tiersVarious—All: error confirmed

No tier, platform, or locale is spared

This is not a niche edge case. The error affects every authenticated loyalty tier from Basic to Platinum Premier Lifetime Elite, all major browsers and operating systems, and at least three distinct regional locales (US, UK, Japan). Authentication state is irrelevant — Guest users are hit with equal frequency.

Critical implication: Your most loyal, highest-value members — the ones with the most points to redeem — are not immune. Platinum Premier Lifetime Elite members show the longest frustration loops, likely because they are most determined to use their points and least willing to give up.
Loyalty Tier Coverage (Confirmed)
TierSessions ReviewedError Observed
Guest (not enrolled)9Yes — all 9
Member (basic)1Yes
Silver Elite2Yes — all 2
Gold Elite2Yes — all 2
Platinum Elite1Yes
Platinum Achiever2Yes — all 2
Platinum Premier Achiever3Yes — all 3
Platinum Premier Lifetime2Yes — all 2
Platform & Browser Coverage (Confirmed)
PlatformBrowserAffected
iOSSafariYes
AndroidChromeYes
macOSChrome, SafariYes
WindowsChrome, EdgeYes
LinuxChromeYes
Regional Locales Confirmed
en-US (United States) en-GB (United Kingdom) /ja/ (Japan)
Property-specific variability explained: Within a single session, a user checking 7 hotels may see the error on 2 of them. This is consistent with a race condition — not a configuration issue. Hotels with faster redemption API responses (e.g., lower inventory complexity, cached availability) resolve before the validation fires. The race is lost only when API latency exceeds the validation window.

Frustration loops, not recoveries

When the error fires, users do not understand that they're stuck. They repeat the same action — visiting Rate List Menu, hitting the same error — in an attempt to recover. The experience produces the classic dead-end frustration pattern Fullstory captures as repeated navigation with zero conversion.

Session Outcomes (23 sessions reviewed)
Abandoned (no booking of any kind) 87% — 20 sessions
Switched to cash rate 9% — 2 sessions
Persistent searching (continued, no resolution) 4% — 1 session
Found hidden escape hatch (View Rates button) 4% — 1 session
Frustration Loop Signature
Average RLM visits per session8.5×
Minimum RLM visits observed1×
Maximum RLM visits observed37×
Sessions with 10+ RLM visits4 sessions (17%)
Sessions with 20+ RLM visits2 sessions (9%)
Peak frustration case: One Platinum Lifetime Elite member in Rancho Cordova visited the Rate List Menu page 37 times in a single session before abandoning. This user checked multiple hotels, multiple date combinations, and never reached a booking page.
The hidden escape hatch: The #RedemptionError element contains a "View Rates" button that bypasses the error state and navigates the user to reviewDetails.mi. Exactly 1 of 23 users (a Silver member in Santa Monica) discovered and successfully used this button. The other 22 did not. The button is present but visually buried inside the error UI, making it effectively invisible without deliberate exploration.

Additional errors compound the experience

Beyond the primary redemption race condition, four additional JavaScript errors were observed across the 23 sessions. Two are independently confirmed by Fullstory's automated opportunity detection.

Error Frequency in Sessions User Impact StoryAI
ReferenceError: Can't find variable: s 11/23 sessions (48%) Fires when user clicks "Select" — even after redemption error UI resolves. Blocks the select action. —
TypeError: Cannot read properties of null (reading 'insertAdjacentHTML') 8/23 sessions (35%) Silent DOM manipulation failure; may prevent rate card rendering —
React hydration errors #418 / #423 7/23 sessions (30%) Server/client state mismatch on mount — may contribute to validation timing issue —
Rate List — "Show With Taxes and Fees" checkbox TypeError Observed in segment TypeError on checkbox interaction; user can still proceed despite the error ★ StoryAI Confirmed
2,987 users · WuNRo59zfFXd
Rate List — Room Selection Area Unresponsive Observed in segment Users repeatedly error-clicking rate/room area; multiple locale versions affected ★ StoryAI Confirmed
233 users · FAt7MX0huesL
The secondary `ReferenceError` is particularly damaging: In the London session, a user who escaped the redemption error by switching to a different hotel then attempted to click "Select" on that hotel's rate — and hit ReferenceError: Can't find variable: s. The one escape route available to persistent users is also broken.

Three actions, prioritized by severity

The root cause is addressable with a targeted fix to the validation timing. Two supporting changes — exposing the existing escape hatch and resolving the secondary Select error — would materially reduce harm for users already in the error state while the primary fix is developed and deployed.

Recommended Actions

These recommendations are sequenced by severity and independence. Fix 1 is the systemic repair. Fixes 2 and 3 are mitigations that can ship independently and faster.

Critical

Fix the race condition — gate validation on API resolution

The client-side validation executing redemptionNotAvailableError must not run until the rewards availability API response is confirmed. Options: (a) move validation into the API response callback, (b) add a loading/pending state that defers the validation pass, (c) check for presence of rewards data before executing the validation path. The simultaneous ×2 fire pattern suggests the validation is being triggered by component re-renders in parallel — worth auditing the React effect dependencies for the validation hook.

High

Surface the existing "View Rates" escape hatch

The #RedemptionError element already contains a "View Rates" button that navigates to reviewDetails.mi. Only 1/23 users discovered it. A simple styling change — larger button, higher contrast, explicit label "Continue to rates" — would allow a meaningful percentage of affected users to recover without waiting for the primary fix. This can ship as a CSS-only change.

Medium

Resolve the ReferenceError: Can't find variable: s

This error fires when users attempt to click "Select" on a rate, including after they have navigated away from an errored property to a clean one. The variable s is referenced but undefined in scope at click-time — likely a scoping or initialization issue with an analytics or tracking library (the single-letter variable name is consistent with a minified analytics SDK). This blocks users who have already partially recovered from the redemption error. Resolving it would give persistent users a real path to completion.

This analysis is a great starting point for an ongoing Fullstory Professional Services engagement. If you'd like this work to be more tailored or continuous, talk to your CSE or Account Executive about getting started.