You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Due for payment 2026-06-25] [$250] Chat - Offline message not displayed when opening video offline #88216
On web browsers, the HTML5 video element retains its buffered data even after the app goes offline (via Troubleshoot "Force offline" or real network loss). Since bufferedPosition > 0, the condition is never satisfied and the offline indicator never appears.
Similarly, the video source replacement at line 127-132 only fires when isLoading is also true — but a fully-buffered video is in readyToPlay state, not loading, so the source is never cleared either.
This doesn't reproduce on native iOS/Android because expo-video's native player doesn't retain buffer state the same way the browser's <video> element does.
Note: The download button is already correctly hidden when offline — both in the attachment modal header and the video popover menu. The bug is isolated to video playback continuing and the offline overlay not appearing.
What changes do you think we should make in order to solve the problem?
The shouldShowOfflineIndicator condition in BaseVideoPlayer.tsx should not require currentTime + bufferedPosition <= 0 when the device is offline. When isVideoOffline is true (after the 7-second OFFLINE_THRESHOLD), the offline indicator should show regardless of the browser's buffer state.
Change the condition at BaseVideoPlayer.tsx:158-160 to:
shouldShowOfflineIndicator = isVideoOffline
And update the replaceAsync('') effect at lines 127-132 to also fire when the video is not loading but is offline — i.e., remove the isLoading guard so that when isVideoOffline && isOffline, the video source is always cleared, stopping playback and preventing the user from interacting with the buffered video.
What alternative solutions did you explore? (Optional)
An alternative would be to gate video rendering at the AttachmentView level (in AttachmentView/index.tsx:370-381) by checking isOffline before rendering AttachmentViewVideo at all — showing AttachmentOfflineIndicator directly instead. However, this would be a larger change and would bypass the existing offline detection mechanism in BaseVideoPlayer that handles the 7-second delay and works correctly on native platforms. Fixing the condition inside BaseVideoPlayer is more surgical and keeps the existing architecture intact.
Next Steps for Contributor+ team: Reply with @MelvinBot implement this to create a draft PR, @MelvinBot <your feedback> to refine this analysis, or explain why you are rejecting Melvin's proposal.
changed the title [-]Chat - Offline message not displayed when opening video offline[/-][+][$250] Chat - Offline message not displayed when opening video offline[/+]on Apr 17, 2026
Please re-state the problem that we are trying to solve in this issue.
When a user goes offline and taps on a video in chat, the video continues playing from its buffer instead of showing the offline indicator message. The download option hiding works correctly, but the offline overlay never appears on web platforms.
What is the root cause of that problem?
The offline indicator condition in BaseVideoPlayer.tsx:158-160 requires currentTime + bufferedPosition <= 0, but on web browsers the HTML5 <video> element retains its buffered data after going offline, so bufferedPosition stays positive and the indicator never shows. The replaceAsync('') call at line 127-132 that would clear the source is also gated on isLoading, which is false for an already-buffered video in readyToPlay state.
What changes do you think we should make in order to solve the problem?
Two changes in BaseVideoPlayer.tsx, single-file fix:
Simplify the offline indicator condition (line 158-160) to show whenever the video is confirmed offline, regardless of buffer state:
Remove the isLoading guard from the replaceAsync('') effect (line 127-132) so the video source is cleared whenever isVideoOffline && isOffline is true, even if the video is already in readyToPlay state. This stops playback of buffered content:
This ensures that on web, once the 7-second OFFLINE_THRESHOLD elapses, the video is stopped and the offline overlay appears — matching native behavior where the buffer is not retained.
What alternative solutions did you explore? (Optional)
Gating at the AttachmentView level by checking isOffline before rendering AttachmentViewVideo would also work but bypasses the existing 7-second threshold delay logic in BaseVideoPlayer and creates a larger change surface across components.
After uploading a video in a chat, forcing the app offline (e.g. via troubleshoot) and opening the video shows playback from cache/buffer, but the offline attachment messaging does not appear and download-related UI does not match the expected offline state (modal / custom controls vs. native controls differ by platform).
2. What is the root cause of that problem?
A. Offline overlay is suppressed whenever the player already has time or buffer
After any decode/buffer, shouldShowOfflineIndicator stays false while offline, so AttachmentOfflineIndicator never shows even though playback can continue (BaseVideoPlayer.tsx L158–L160):
3. What changes do you think we should make in order to solve the problem?
Patch 1 — Show offline overlay for remote video whenever we treat the session as offline for this player
Decouple “show offline UX” from “no bytes buffered yet.” For example, drive the overlay from isVideoOffline (or isOffline) and!isUploading (local blob uploads already use ATTACHMENT_LOCAL_URL_PREFIX), and remove the currentTime + bufferedPosition <= 0 requirement, or replace it with a narrower check (e.g. only skip overlay for purely local preview URLs).
Re-test: controls block that checks !shouldShowOfflineIndicator (L598–600) should still hide custom controls when the overlay shows.
Patch 2 — Align offline UI timing with the rest of the app
Either reduce OFFLINE_THRESHOLD for video-only UX, or use isOffline for AttachmentOfflineIndicator while keeping delayed isVideoOffline only for replaceAsync('') (L127–132) if that delay is still required for cache detection.
Patch 3 — Native fullscreen
Implement native equivalent of hiding download (platform-specific fullscreen / VideoView options), or force custom controls when offline so behavior matches web.
4. An alternative considered
Aggressive: On isOffline for non-local URLs, call pause(), clear/replace the source (similar to L127–132), and rely on AttachmentOfflineIndicator + no playback until back online. This matches “no playback while offline” but is harsher if product wants to allow buffered-only viewing with a clear offline banner—Patch 1 matches the stated expected result without blocking cache playback entirely.
⚠️@KJ21-ENG Your proposal is a duplicate of an already existing proposal and has been automatically withdrawn to prevent spam. Please review the existing proposals before submitting a new one.
Please re-state the problem that we are trying to solve in this issue.
When a chat video attachment is opened on web after the device goes offline, the fullscreen attachment viewer silently plays the video from the browser HTTP cache instead of showing the offline indicator. The user never sees the "You appear to be offline" message that is expected for other offline attachment interactions.
Affected platforms: Android mWeb Chrome, iOS mWeb Safari / Chrome, Windows Chrome, macOS Chrome/Safari. Native iOS App and native Android App are not checked in the report, which is consistent with the root cause being specific to the browser's HTTP media cache.
What is the root cause of that problem?
There are two cooperating conditions in the video player that together suppress the offline indicator after a fresh upload.
Condition 1 — the preview on web silently warms the browser HTTP cache with the freshly uploaded video. On web, after upload, VideoPlayerPreview creates a hidden <video> element and calls .load() on it just to measure the real video dimensions:
That measurement request is enough for the browser to cache the video bytes (and the HTTP response) against the encrypted URL even though the chat surface only ever displays a static thumbnail in narrow layout. Once the user goes offline and taps the thumbnail, the fresh BaseVideoPlayer instance in the attachment modal re-requests the same URL and the browser serves it from its HTTP media cache. This does not happen on native App (no hidden <video> element, no web HTTP cache) — matching the "Platforms" checklist in the report.
Condition 2 — BaseVideoPlayer's shouldShowOfflineIndicator is only true while nothing has buffered, and isVideoOffline only becomes true 7 seconds after isOffline flips. On mount in the attachment modal:
shouldShowOfflineIndicator requires currentTime + bufferedPosition <= 0. Because the bytes are served from the browser cache, the player immediately reports a non-zero buffered position and, via the readyToPlay auto-play branch, starts incrementing currentTime — so the sum is never <= 0.
That auto-play branch plays the video whenever the status reaches readyToPlay, with no check against the network state, so a cached video starts playing the moment the modal opens.
Compounding both conditions, isVideoOffline is initialized to false and only flips to true 7 seconds after isOffline becomes true:
So even if the buffer check were relaxed, the indicator could not appear for 7 seconds on a newly mounted player. By the time isVideoOffline is finally true, cached playback has already produced currentTime > 0 and bufferedPosition > 0, and the indicator stays suppressed forever.
The same AttachmentOfflineIndicator component is already used correctly for non-cached flows, so the regression is entirely in how BaseVideoPlayer derives shouldShowOfflineIndicator and gates the auto-play when the player is mounted while the device is already confirmed offline. The 7-second OFFLINE_THRESHOLD was introduced to absorb intermittent network blips during ongoing playback — it was not meant to apply to the "mount in an already-offline state" case.
What changes do you think we should make in order to solve the problem?
Treat "mounted while already offline" as a distinct, confirmed-offline case in BaseVideoPlayer, rather than waiting 7 seconds and relying on buffered position.
Concretely:
In src/components/VideoPlayer/BaseVideoPlayer.tsx, make the "is confirmed offline" state reflect the initial network state instead of always starting at false. If the player is constructed while isOffline is already true, treat the offline state as confirmed immediately (the 7-second threshold is only needed for in-flight flips during playback, not for a fresh mount). The existing effect that watches isOffline and sets the timer remains in charge of the flip case.
Stop auto-playing when the player reaches readyToPlay while isOffline is true. Today the statusChange listener calls playVideo() whenever isFirstLoad is true and the player is the current one; it should additionally require that the network is online. This ensures currentTime stays at 0 for a cached-but-offline video and prevents the user from silently consuming a cached copy without being told they are offline.
Simplify shouldShowOfflineIndicator so it no longer depends on currentTime + bufferedPosition <= 0. Show the indicator whenever the player is confirmed offline and the user is not actively watching (i.e., not currently playing) and we are not uploading a new video. Combined with change 2, this means: the indicator appears as soon as a cached video is opened while offline, stays hidden while a video continues to play through an intermittent network blip, and reappears once playback stalls because the buffer has exhausted.
Together, these three adjustments give the modal the same observable behaviour a user would see for a non-cached video: the offline message appears, the built-in download affordance stays hidden (the existing shouldShowDownloadButton check in AttachmentModalBaseContent already gates on !isOffline), and the player refuses to silently play cached bytes that bypass the online/offline distinction.
The fix only touches src/components/VideoPlayer/BaseVideoPlayer.tsx. No changes are required in AttachmentOfflineIndicator.tsx, AttachmentView, AttachmentModalBaseContent, or the preview — those surfaces all respond correctly once BaseVideoPlayer reports the right shouldShowOfflineIndicator value and stops auto-playing.
What alternative solutions did you explore? (Optional)
Forcing VideoPlayerPreview to skip the hidden <video> dimension probe when offline was considered, because it is that probe which seeds the browser HTTP cache. This was rejected because (a) the cache is also seeded the first time the user views the thumbnail on a wide layout and (b) any future path that ever fetches the URL while online would still poison the cache. The proper place to authoritatively decide "we are offline, do not play" is the player itself, not every upstream consumer.
Clearing the video source via replaceAsync('') on mount when offline was also considered. The existing replaceAsync('') effect already runs when the player is loading while offline, but it is conditioned on isVideoOffline && isLoading && isOffline, so it only fires after the 7-second threshold and only while status is still loading. By the time a cached source reaches readyToPlay, isLoading is already false and that effect never runs. Forcing the source to be cleared would also interact badly with the reconnect flow, which expects to restore the original sourceURL only when currentTime <= 0 && hasError. Fixing shouldShowOfflineIndicator and the auto-play gate keeps the reconnect path intact and avoids the need to reason about an empty source.
[Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.
Link to discussion:
[Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.
Regression Test Proposal Template
[BugZero Assignee] Create a GH issue for creating/updating the regression test once above steps have been agreed upon.
1. Navigate to any chat
2. Upload a video
3. Disable the internet connection via troubleshoot
4. Click on the video
5. Verify that an offline message is displayed and download option is not displayed
Activity
MelvinBot commentedon Apr 17, 2026
Proposal
What is the root cause of that problem?
The offline indicator for videos is gated on having zero buffered content. In
BaseVideoPlayer.tsx:158-160:On web browsers, the HTML5 video element retains its buffered data even after the app goes offline (via Troubleshoot "Force offline" or real network loss). Since
bufferedPosition > 0, the condition is never satisfied and the offline indicator never appears.Similarly, the video source replacement at line 127-132 only fires when
isLoadingis also true — but a fully-buffered video is inreadyToPlaystate, notloading, so the source is never cleared either.This doesn't reproduce on native iOS/Android because
expo-video's native player doesn't retain buffer state the same way the browser's<video>element does.Note: The download button is already correctly hidden when offline — both in the attachment modal header and the video popover menu. The bug is isolated to video playback continuing and the offline overlay not appearing.
What changes do you think we should make in order to solve the problem?
The
shouldShowOfflineIndicatorcondition inBaseVideoPlayer.tsxshould not requirecurrentTime + bufferedPosition <= 0when the device is offline. WhenisVideoOfflineis true (after the 7-secondOFFLINE_THRESHOLD), the offline indicator should show regardless of the browser's buffer state.Change the condition at
BaseVideoPlayer.tsx:158-160to:And update the
replaceAsync('')effect at lines 127-132 to also fire when the video is not loading but is offline — i.e., remove theisLoadingguard so that whenisVideoOffline && isOffline, the video source is always cleared, stopping playback and preventing the user from interacting with the buffered video.What alternative solutions did you explore? (Optional)
An alternative would be to gate video rendering at the
AttachmentViewlevel (inAttachmentView/index.tsx:370-381) by checkingisOfflinebefore renderingAttachmentViewVideoat all — showingAttachmentOfflineIndicatordirectly instead. However, this would be a larger change and would bypass the existing offline detection mechanism inBaseVideoPlayerthat handles the 7-second delay and works correctly on native platforms. Fixing the condition insideBaseVideoPlayeris more surgical and keeps the existing architecture intact.Next Steps for Contributor+ team: Reply with
@MelvinBot implement thisto create a draft PR,@MelvinBot <your feedback>to refine this analysis, or explain why you are rejecting Melvin's proposal.melvin-bot commentedon Apr 17, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @Ollyws (
External)[-]Chat - Offline message not displayed when opening video offline[/-][+][$250] Chat - Offline message not displayed when opening video offline[/+]melvin-bot commentedon Apr 17, 2026
Job added to Upwork: https://www.upwork.com/jobs/~022045202730445059794
JustDreameritis commentedon Apr 17, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
When a user goes offline and taps on a video in chat, the video continues playing from its buffer instead of showing the offline indicator message. The download option hiding works correctly, but the offline overlay never appears on web platforms.
What is the root cause of that problem?
The offline indicator condition in
BaseVideoPlayer.tsx:158-160requirescurrentTime + bufferedPosition <= 0, but on web browsers the HTML5<video>element retains its buffered data after going offline, sobufferedPositionstays positive and the indicator never shows. ThereplaceAsync('')call at line 127-132 that would clear the source is also gated onisLoading, which is false for an already-buffered video inreadyToPlaystate.What changes do you think we should make in order to solve the problem?
Two changes in
BaseVideoPlayer.tsx, single-file fix:isLoadingguard from thereplaceAsync('')effect (line 127-132) so the video source is cleared wheneverisVideoOffline && isOfflineis true, even if the video is already inreadyToPlaystate. This stops playback of buffered content:This ensures that on web, once the 7-second
OFFLINE_THRESHOLDelapses, the video is stopped and the offline overlay appears — matching native behavior where the buffer is not retained.What alternative solutions did you explore? (Optional)
Gating at the
AttachmentViewlevel by checkingisOfflinebefore renderingAttachmentViewVideowould also work but bypasses the existing 7-second threshold delay logic inBaseVideoPlayerand creates a larger change surface across components.skylarkerx commentedon Apr 17, 2026
1. Problem description
After uploading a video in a chat, forcing the app offline (e.g. via troubleshoot) and opening the video shows playback from cache/buffer, but the offline attachment messaging does not appear and download-related UI does not match the expected offline state (modal / custom controls vs. native controls differ by platform).
2. What is the root cause of that problem?
A. Offline overlay is suppressed whenever the player already has time or buffer
After any decode/buffer,
shouldShowOfflineIndicatorstays false while offline, soAttachmentOfflineIndicatornever shows even though playback can continue (BaseVideoPlayer.tsxL158–L160):B. “Offline” for the player UI is delayed by several seconds
BaseVideoPlayer.tsx(L114–L125) setsisVideoOfflineonly afterCONST.VIDEO_PLAYER.OFFLINE_THRESHOLD(7000 ms), so the offline UI lags behinduseNetwork().isOffline.C. Native mobile: no
nodownloadon native fullscreen controlsuseHandleNativeVideoControls/index.native.tsis a no-op, while the web implementation setscontrolsList="nodownload"when offline.BaseVideoPlayerenablesnativeControlsin fullscreen, so browsers/OS may still expose download where web custom logic would hide it.Note: The video popover already omits download when offline (
VideoPopoverMenuContext.tsxL70–78), and the attachment modal hides the download button when offline (AttachmentModalBaseContent/index.tsxL190–197)—so gaps are mainly the overlay gating/delay and native fullscreen.3. What changes do you think we should make in order to solve the problem?
Patch 1 — Show offline overlay for remote video whenever we treat the session as offline for this player
Decouple “show offline UX” from “no bytes buffered yet.” For example, drive the overlay from
isVideoOffline(orisOffline) and!isUploading(local blob uploads already useATTACHMENT_LOCAL_URL_PREFIX), and remove thecurrentTime + bufferedPosition <= 0requirement, or replace it with a narrower check (e.g. only skip overlay for purely local preview URLs).Brief sketch:
const shouldShowOfflineIndicator = useMemo(() => { - return isVideoOffline && currentTime + bufferedPosition <= 0; -}, [bufferedPosition, currentTime, isVideoOffline]); + return isVideoOffline && !isUploading; +}, [isVideoOffline, isUploading]);Re-test: controls block that checks
!shouldShowOfflineIndicator(L598–600) should still hide custom controls when the overlay shows.Patch 2 — Align offline UI timing with the rest of the app
Either reduce
OFFLINE_THRESHOLDfor video-only UX, or useisOfflineforAttachmentOfflineIndicatorwhile keeping delayedisVideoOfflineonly forreplaceAsync('')(L127–132) if that delay is still required for cache detection.Patch 3 — Native fullscreen
Implement native equivalent of hiding download (platform-specific fullscreen /
VideoViewoptions), or force custom controls when offline so behavior matches web.4. An alternative considered
Aggressive: On
isOfflinefor non-local URLs, callpause(), clear/replace the source (similar to L127–132), and rely onAttachmentOfflineIndicator+ no playback until back online. This matches “no playback while offline” but is harsher if product wants to allow buffered-only viewing with a clear offline banner—Patch 1 matches the stated expected result without blocking cache playback entirely.KJ21-ENG commentedon Apr 17, 2026
🚫 Duplicated proposal withdrawn by 🤖 ProposalPolice.
github-actions commentedon Apr 17, 2026
wildan-m commentedon Apr 17, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
When a chat video attachment is opened on web after the device goes offline, the fullscreen attachment viewer silently plays the video from the browser HTTP cache instead of showing the offline indicator. The user never sees the "You appear to be offline" message that is expected for other offline attachment interactions.
Affected platforms: Android mWeb Chrome, iOS mWeb Safari / Chrome, Windows Chrome, macOS Chrome/Safari. Native iOS App and native Android App are not checked in the report, which is consistent with the root cause being specific to the browser's HTTP media cache.
What is the root cause of that problem?
There are two cooperating conditions in the video player that together suppress the offline indicator after a fresh upload.
Condition 1 — the preview on web silently warms the browser HTTP cache with the freshly uploaded video. On web, after upload,
VideoPlayerPreviewcreates a hidden<video>element and calls.load()on it just to measure the real video dimensions:App/src/components/VideoPlayerPreview/index.tsx
Lines 69 to 88 in 3f38b2e
That measurement request is enough for the browser to cache the video bytes (and the HTTP response) against the encrypted URL even though the chat surface only ever displays a static thumbnail in narrow layout. Once the user goes offline and taps the thumbnail, the fresh
BaseVideoPlayerinstance in the attachment modal re-requests the same URL and the browser serves it from its HTTP media cache. This does not happen on native App (no hidden<video>element, no web HTTP cache) — matching the "Platforms" checklist in the report.Condition 2 —
BaseVideoPlayer'sshouldShowOfflineIndicatoris only true while nothing has buffered, andisVideoOfflineonly becomes true 7 seconds afterisOfflineflips. On mount in the attachment modal:App/src/components/VideoPlayer/BaseVideoPlayer.tsx
Lines 158 to 160 in 3f38b2e
shouldShowOfflineIndicatorrequirescurrentTime + bufferedPosition <= 0. Because the bytes are served from the browser cache, the player immediately reports a non-zero buffered position and, via thereadyToPlayauto-play branch, starts incrementingcurrentTime— so the sum is never<= 0.App/src/components/VideoPlayer/BaseVideoPlayer.tsx
Lines 293 to 310 in 3f38b2e
That auto-play branch plays the video whenever the status reaches
readyToPlay, with no check against the network state, so a cached video starts playing the moment the modal opens.Compounding both conditions,
isVideoOfflineis initialized tofalseand only flips totrue7 seconds afterisOfflinebecomes true:App/src/components/VideoPlayer/BaseVideoPlayer.tsx
Lines 114 to 125 in 3f38b2e
So even if the buffer check were relaxed, the indicator could not appear for 7 seconds on a newly mounted player. By the time
isVideoOfflineis finally true, cached playback has already producedcurrentTime > 0andbufferedPosition > 0, and the indicator stays suppressed forever.The same
AttachmentOfflineIndicatorcomponent is already used correctly for non-cached flows, so the regression is entirely in howBaseVideoPlayerderivesshouldShowOfflineIndicatorand gates the auto-play when the player is mounted while the device is already confirmed offline. The 7-secondOFFLINE_THRESHOLDwas introduced to absorb intermittent network blips during ongoing playback — it was not meant to apply to the "mount in an already-offline state" case.What changes do you think we should make in order to solve the problem?
Treat "mounted while already offline" as a distinct, confirmed-offline case in
BaseVideoPlayer, rather than waiting 7 seconds and relying on buffered position.Concretely:
In
src/components/VideoPlayer/BaseVideoPlayer.tsx, make the "is confirmed offline" state reflect the initial network state instead of always starting atfalse. If the player is constructed whileisOfflineis alreadytrue, treat the offline state as confirmed immediately (the 7-second threshold is only needed for in-flight flips during playback, not for a fresh mount). The existing effect that watchesisOfflineand sets the timer remains in charge of the flip case.Stop auto-playing when the player reaches
readyToPlaywhileisOfflineis true. Today thestatusChangelistener callsplayVideo()wheneverisFirstLoadis true and the player is the current one; it should additionally require that the network is online. This ensurescurrentTimestays at0for a cached-but-offline video and prevents the user from silently consuming a cached copy without being told they are offline.Simplify
shouldShowOfflineIndicatorso it no longer depends oncurrentTime + bufferedPosition <= 0. Show the indicator whenever the player is confirmed offline and the user is not actively watching (i.e., not currently playing) and we are not uploading a new video. Combined with change 2, this means: the indicator appears as soon as a cached video is opened while offline, stays hidden while a video continues to play through an intermittent network blip, and reappears once playback stalls because the buffer has exhausted.Together, these three adjustments give the modal the same observable behaviour a user would see for a non-cached video: the offline message appears, the built-in download affordance stays hidden (the existing
shouldShowDownloadButtoncheck inAttachmentModalBaseContentalready gates on!isOffline), and the player refuses to silently play cached bytes that bypass the online/offline distinction.The fix only touches
src/components/VideoPlayer/BaseVideoPlayer.tsx. No changes are required inAttachmentOfflineIndicator.tsx,AttachmentView,AttachmentModalBaseContent, or the preview — those surfaces all respond correctly onceBaseVideoPlayerreports the rightshouldShowOfflineIndicatorvalue and stops auto-playing.Compare branch: https://github.com/Expensify/App/compare/main...wildan-m:App:wildan/88216-video-offline-indicator-missing?expand=1
What alternative solutions did you explore? (Optional)
Forcing
VideoPlayerPreviewto skip the hidden<video>dimension probe when offline was considered, because it is that probe which seeds the browser HTTP cache. This was rejected because (a) the cache is also seeded the first time the user views the thumbnail on a wide layout and (b) any future path that ever fetches the URL while online would still poison the cache. The proper place to authoritatively decide "we are offline, do not play" is the player itself, not every upstream consumer.Clearing the video source via
replaceAsync('')on mount when offline was also considered. The existingreplaceAsync('')effect already runs when the player is loading while offline, but it is conditioned onisVideoOffline && isLoading && isOffline, so it only fires after the 7-second threshold and only while status is stillloading. By the time a cached source reachesreadyToPlay,isLoadingis alreadyfalseand that effect never runs. Forcing the source to be cleared would also interact badly with the reconnect flow, which expects to restore the originalsourceURLonly whencurrentTime <= 0 && hasError. FixingshouldShowOfflineIndicatorand the auto-play gate keeps the reconnect path intact and avoids the need to reason about an empty source.51 remaining items
Ollyws commentedon Jun 30, 2026
Hmm Melvin isn't listening.
Ollyws commentedon Jun 30, 2026
@MelvinBot Tell me which PR caused this bug.
Ollyws commentedon Jun 30, 2026
BugZero Checklist:
Bug classification
Source of bug:
Where bug was reported:
Who reported the bug:
[Contributor] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake.
Link to comment: https://github.com/Expensify/App/pull/75270/changes#r3500156403
[Contributor] If the regression was CRITICAL (e.g. interrupts a core flow) A discussion in #expensify-open-source has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner.
Link to discussion:
[Contributor] If it was decided to create a regression test for the bug, please propose the regression test steps using the template below to ensure the same bug will not reach production again.
[BugZero Assignee] Create a GH issue for creating/updating the regression test once above steps have been agreed upon.
Link to issue: https://github.com/Expensify/Expensify/issues/654716
Regression Test Proposal
Precondition:
Test:
Do we agree 👍 or 👎
Zapier Logs
Run ID: 00040eee-0ac3-a238-6e8a-ac96565599b4Zapier Logs
Run ID: 00040eee-9e2d-a585-e161-2f6abf9201d4Ollyws commentedon Jun 30, 2026
@mallenexpensify checklist done and payment requested.
nabi-ebrahimi commentedon Jul 2, 2026
@mallenexpensify, could you please reopen this issue? I haven’t been paid yet.
You already hired me here: #88216 (comment), but I still haven’t received the payment.
Thank you!
mallenexpensify commentedon Jul 2, 2026
@nabi-ebrahimi paid, summary updated above. Thx.
^ Test case created. Thx
flaviadefaria commentedon Jul 7, 2026
Approved: @Ollyws due $250 via NewDot