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
A user lost access to BB on their iPhone: both the existing Safari tab at https://brsbl.getbb.app/ and the native BB app showed a persistent black/blank screen. A fresh Private-browser tab worked after sign-in, providing a workaround. Clearing website data and signing in again did not restore the native app; recovery attempts also produced HTTP 401, and the user separately reported HTTP 503 screens.
Inspection of the affected Safari tab confirmed that it repeatedly loaded a truncated cached startup JavaScript file, which failed to parse before the app could render. Fetching the complete file and reloading restored app mounting, including on a subsequent normal reload. The native app remained blank until the user deleted and reinstalled it, which they confirmed restored access.
The Safari blank-screen mechanism is established, but why the file became truncated and cacheable remains unknown. The native app's failing state was not captured, so neither the same corruption nor an authentication problem is established as its cause. Access is recovered; preventing recurrence and making recovery reliable remain open.
Versions and environment
Incident reported September 16, 2026, approximately 13:12–13:30 America/New_York; affected phone inspected at approximately 14:42–14:45.
Phone: iOS 26.6.1, confirmed by Safari’s device inspector. Affected browser: regular iPhone Safari tab. Phone model and native BB app build remain unknown.
Host BB CLI: 0.43.2-nightly.34866755923.1, packaged Nightly on macOS 26.5.2 (25F84). Inspecting Mac Safari: 26.5.2. The successful nightly publication run maps this host version to commit d89160eb8c69c1e3ebc2ba2514f1711af8d7c506 (September 14). This is host build provenance, not the unknown native app build.
Latest successful repository-recorded Connect deployment before the incident: September 12, commit 3b37d2790d084a47c96eb78267da5d159598f203, Worker version 27889535-f8a2-413d-9868-6ace3330b64c. Deployment logs establish this record; out-of-band deployments cannot be excluded without Cloudflare access.
Connect server: https://brsbl.getbb.app/.
Source inspected: e6c615b87056ed2a3aedd46b4c01064f6fa132a9; latest comparison with fetched origin/main at c024ceac524882b7bf9fbef41c14c4911919de4c. Relevant relay/cache/session code and static asset serving logic are unchanged. The deployed-gate record has the same inspected relay/cache/encoding code; the reported host nightly has the same inspected host static-serving and tunnel-client code. This is source comparison, not a reproduction of the initiating failure on main. Native source has evolved since the host nightly and must not be used to infer the installed phone version.
Steps to reproduce
Confirmed browser failure and recovery
This reproduces the reporter’s existing damaged cache, not a deterministic way to create it from a clean installation.
Open the existing regular Safari tab at https://brsbl.getbb.app/ on the affected iPhone. The page is black/blank. Adding a query string to the document URL does not recover it.
Attach Mac Safari Web Inspector to that iPhone tab and reload normally.
Observe an empty #root, the startup script loaded from memory cache, and the syntax error below.
Export the network trace locally and compare the cached startup response with fresh responses for /assets/index-BaDU-L7_.js (exact URL and a cache-busted URL with cache: no-store). The cached body is an exact prefix of both complete responses.
After fetching the complete responses and reloading, observe populated app DOM and resumed application requests. Repeat a normal reload: app mounting succeeds and the startup SyntaxError does not return. The reporter’s visual confirmation has not been obtained.
A fresh Private-browser tab also worked after sign-in. No explicit cookie/site-data deletion or new sign-in was needed during the inspected regular-tab recovery.
Native failure and recovery, reporter-observed
The native BB app’s saved connection initially shows a blank page.
Long-press the home-screen BB icon → Device settings → Clear website data. This does not restore access; the reporter subsequently captures HTTP 401.
Generate a fresh code on the host with bb connect machine-code. On the phone, use Device settings → Servers → long-press server → Sign in again, then redeem the code.
The code lookup confirms consumed: true; the reporter still sees the same 401 screen. The phone’s post-pairing cookie installation/transmission is unverified.
After the browser recovery, the reporter confirms the native app is still blank.
Delete and reinstall the native BB app: the reporter confirms this fixes it. Whether the same build was reinstalled and whether fresh pairing/sign-in was required have not been confirmed. The old native state is no longer available for inspection.
Expected vs actual
Expected: complete startup assets execute and BB loads; failed transfers should not leave a persistently unusable cached app. Native recovery should restore a usable session.
Actual browser console:
SyntaxError: Unexpected end of script
/assets/index-BaDU-L7_.js:26
Native error captured during failed recovery (before the successful reinstall):
The server answered with an error
HTTP 401
Try again
Device settings
HTTP 503 screens were also reported. Their exact timing, client, and response body remain unknown.
Causal mechanism: truncated immutable script cached on the phone → reload reuses it → parsing fails before React mounts → empty black page. Changing the document query leaves the hashed script URL unchanged. Private browsing avoids the damaged cache. Authentication does not explain this reproduced browser failure.
Both fresh phone fetches returned the same complete bytes: the exact-URL fetch arrived with zstd, and the cache-busted fetch with Brotli. This does not establish a compression-specific defect. The startup error happens before React and its error boundary are installed, explaining the lack of an in-app crash panel.
Raw HAR headers were not published because they can contain credentials. The temporary HAR was removed after extracting and verifying the measurements. The malformed bytes remain reproducible from the original complete asset: take its first 832,191 bytes; that prefix reproduces the captured bad SHA-256 exactly. This reconstructs the payload, not the original cache-writing failure.
Healthy origin representations
Fresh HTTP reads of the same asset from the host origin http://127.0.0.1:38886 all completed normally. Each decoded to 1,011,640 bytes and the good SHA-256 above:
Requested representation
Wire bytes
Origin Content-Length
Decoded hash
Identity
1,011,640
1,011,640
Good hash above
Brotli
237,668
237,668
Good hash above
Gzip
300,285
300,285
Good hash above
The host static handler reads the asset into memory and supplies the compressed file length for precompressed responses. These checks rule out a persistently malformed current origin artifact, not a transient failure during the original transfer. The captured failed response headers contained no Content-Length.
Lead for the initiating truncation event
The cached response predates daytime troubleshooting. Host server.69.log shows a tunnel interruption about 68 seconds after its response timestamp:
The wider 00:53–01:04 UTC host log window also contains missed tunnel heartbeats at 00:53:08.093, 00:54:10.654, and 01:00:54.236. At 00:59:04.922 an npm lookup was aborted; at 00:59:05.534 a host lookup failed with host_unavailable. These support broader instability around the download, without identifying the failing layer. A bounded macOS power-log check found no Sleep/Wake transition in this window; this does not exclude network loss or scheduling stalls.
Heartbeat detection runs every 20 seconds with a 60-second acknowledgment deadline (source). Therefore the logged disconnect time is detection time, not a precise timestamp for the first lost byte.
Use the original response timestamp and ray ID to inspect edge logs. x-bb-cache: miss is a stored response header, not proof that every later delivery bypassed all caches; another Cloudflare cache layer can replay it. Host logs do not record byte counts for this asset request: detailed response-size logging is limited to initial thread-load APIs. Cloudflare request logs/runtime traces were unavailable with the investigation’s credentials.
Transport and cache source audit: leads, not a proven initiating defect
The host tunnel client sends body-end after consuming the origin response; an origin read error goes through close-stream. The edge closes normally on body-end, while disconnect handling requests a stream abort. Source inspection did not prove that a disconnect is intentionally converted into successful EOF.
The edge relay uses an ordinary TransformStream, with no expected-length accounting before accepting body-end; that protocol message carries no byte count or digest. Cloudflare documents that manually set lengths are ignored for arbitrary streaming bodies. Its FixedLengthStream can enforce exact byte counts. This identifies a potential integrity-check improvement, not proof that its absence caused this incident; compression/transcoding boundaries must be handled correctly.
Asset caching clones and streams cacheable successful responses into cache.put while serving the visitor. No application-level asset checksum is checked. The observed incomplete response nevertheless being reusable is proven; which layer treated it as complete is not.
Do not blindly change the response encoding mode: PR #915 established that the relay/cache-hit paths need manual encoding while the cache-miss path is automatically decoded/re-encoded. Its raw-gzip corruption differs from this exact plaintext-prefix truncation.
Existing Node-level stream replacement coverage expects a pending body read to reject. Existing workerd encoding tests cover complete compressed bodies and cache hits/misses. Neither demonstrates interrupted, partially delivered compressed assets through edge caching and actual Safari. These tests were read, not run in this diagnosis.
In installed react-native-webview@13.16.1, iOS clearCache(true) includes localStorage, sessionStorage and IndexedDB. However, BB unmounts the WebView on the HTTP error screen, so the optional-ref cache clear then does nothing while cookie clearing still runs. The “Cleared” toast acknowledges command delivery, not completed deletion. Earlier troubleshooting advice that this dependency never clears local storage was incorrect.
Direct server requests confirmed: valid cookie → 200; omit cookie → 401; retry without it → 401; restore it → 200. This is direct server evidence plus source tracing, not an independently reproduced native UI sequence. The gate’s 401 sign-in HTML is hidden by BB’s generic native error panel when the WebView is unmounted.
A further startup-detection limitation: native onLoadEnd marks the page ready without proving that the app JavaScript mounted. This can fail to surface a bundle startup error, but the native bundle error was not captured here.
Recommended recovery direction: await data clearing, reinstall a fresh Connect session before reload, and route page-level 401 through session recovery. Cache clearing must also work without a mounted WebView. Fresh pairing changes the connection identity and should already mint/install a cookie, so its reported failure is not explained solely by the reset defect. Still needed: the native page’s failing URL/status and cookie-presence/validation result, without disclosing token values, plus the native app build.
HTTP 503 recovery limitation
Connect emits HTTP 503 when no open host tunnel is available. Its HTML error page refreshes every ten seconds, but the native app replaces main-frame HTTP errors with its generic panel and unmounts the page, preventing that HTML recovery from running. This is a source-level recovery limitation; the reporter’s uncaptured 503 responses cannot yet be attributed to this specific path.
Fresh public startup assets were complete; the damaged phone copy differs from them. Earlier healthy host/network checks did not examine that cache.
The browser blank screen is reproduced and explained. The original event that allowed an incomplete response into cache is not yet established.
Native cache corruption has not been verified. Reinstalling recovered access; the reasons for its earlier blank screen, failed re-pair recovery, and reported 503s remain unproven. A changed app build or session during reinstall is a possible confound.
Inspection limitation: after reconnecting/unlocking the iPhone, Mac Safari exposed its Safari tabs but no native BB WebView. Current BB source gates WebView debugging on __DEV__. The installed app build remains unknown; this explains the expected release-build limitation but does not diagnose its blank screen. macOS Console did not list the phone as an available log source.
Earlier clean source-app checks in Chrome for Testing and desktop Safari did not reproduce the damaged phone state. No native simulator was available.
No product code changes, PR, deployment, or local tests were made.
Remaining investigation and verification
Available incident evidence, source/history, origin representations, publication/deployment records, and bounded host/power logs have been examined. No production restart, cache purge, configuration change, code change, or deliberate connection interruption was performed.
To establish the initiating defect, the next useful work is:
With authorized Cloudflare access, correlate ray a3bbec720a237c96-EWR and the original timestamp with request outcomes, stream errors, cache status and byte counts if those fields were retained. Historical metadata may be insufficient to recover the original cause.
In an isolated environment, interrupt host/tunnel and visitor connections partway through a compressed immutable asset; verify that the response errors and neither edge nor Safari reuses a partial success. Cover cache miss/hit and slow-reader backpressure. This fault-injection reproduction was not performed; local tests are prohibited in this workspace and no remote test change was created for this diagnosis.
Verify recovery with a deliberately damaged cached startup asset: startup failure should be visible, recovery must fetch valid assets, and native data clearing must renew the session rather than leaving 401. Verify this in real iOS Safari and the native WebView.
The user's reinstall removed the old native state. Without a new occurrence or reproducible fault injection, identical browser/native truncation cannot be proven retrospectively.
Suggested priority and effort
High: one user lost browser and native access until fresh asset retrieval or reinstall. Access is now recovered; the permanent prevention/recovery fix is still open. Breadth is unknown; no server data loss was reported.
Summary
A user lost access to BB on their iPhone: both the existing Safari tab at
https://brsbl.getbb.app/and the native BB app showed a persistent black/blank screen. A fresh Private-browser tab worked after sign-in, providing a workaround. Clearing website data and signing in again did not restore the native app; recovery attempts also produced HTTP 401, and the user separately reported HTTP 503 screens.Inspection of the affected Safari tab confirmed that it repeatedly loaded a truncated cached startup JavaScript file, which failed to parse before the app could render. Fetching the complete file and reloading restored app mounting, including on a subsequent normal reload. The native app remained blank until the user deleted and reinstalled it, which they confirmed restored access.
The Safari blank-screen mechanism is established, but why the file became truncated and cacheable remains unknown. The native app's failing state was not captured, so neither the same corruption nor an authentication problem is established as its cause. Access is recovered; preventing recurrence and making recovery reliable remain open.
Versions and environment
0.43.2-nightly.34866755923.1, packaged Nightly on macOS 26.5.2 (25F84). Inspecting Mac Safari: 26.5.2. The successful nightly publication run maps this host version to commitd89160eb8c69c1e3ebc2ba2514f1711af8d7c506(September 14). This is host build provenance, not the unknown native app build.3b37d2790d084a47c96eb78267da5d159598f203, Worker version27889535-f8a2-413d-9868-6ace3330b64c. Deployment logs establish this record; out-of-band deployments cannot be excluded without Cloudflare access.https://brsbl.getbb.app/.e6c615b87056ed2a3aedd46b4c01064f6fa132a9; latest comparison with fetchedorigin/mainatc024ceac524882b7bf9fbef41c14c4911919de4c. Relevant relay/cache/session code and static asset serving logic are unchanged. The deployed-gate record has the same inspected relay/cache/encoding code; the reported host nightly has the same inspected host static-serving and tunnel-client code. This is source comparison, not a reproduction of the initiating failure on main. Native source has evolved since the host nightly and must not be used to infer the installed phone version.Steps to reproduce
Confirmed browser failure and recovery
This reproduces the reporter’s existing damaged cache, not a deterministic way to create it from a clean installation.
https://brsbl.getbb.app/on the affected iPhone. The page is black/blank. Adding a query string to the document URL does not recover it.#root, the startup script loaded from memory cache, and the syntax error below./assets/index-BaDU-L7_.js(exact URL and a cache-busted URL withcache: no-store). The cached body is an exact prefix of both complete responses.A fresh Private-browser tab also worked after sign-in. No explicit cookie/site-data deletion or new sign-in was needed during the inspected regular-tab recovery.
Native failure and recovery, reporter-observed
bb connect machine-code. On the phone, use Device settings → Servers → long-press server → Sign in again, then redeem the code.consumed: true; the reporter still sees the same 401 screen. The phone’s post-pairing cookie installation/transmission is unverified.Expected vs actual
Expected: complete startup assets execute and BB loads; failed transfers should not leave a persistently unusable cached app. Native recovery should restore a usable session.
Actual browser console:
Native error captured during failed recovery (before the successful reinstall):
HTTP 503 screens were also reported. Their exact timing, client, and response body remain unknown.
Evidence
Confirmed truncated cache entry
5fea59a405972cb2f24f7b61da9ee1cb0c9b357493eb5110e4103cec241e2db185a209186bb8f3d0d1dac1b6d4ae95f2342436dcd0a2d55bf68e39a2d34dbe74The cached body is an exact prefix of the complete file, missing 179,449 bytes, and ends mid-assignment:
The failing response records HTTP 200 and:
Causal mechanism: truncated immutable script cached on the phone → reload reuses it → parsing fails before React mounts → empty black page. Changing the document query leaves the hashed script URL unchanged. Private browsing avoids the damaged cache. Authentication does not explain this reproduced browser failure.
Both fresh phone fetches returned the same complete bytes: the exact-URL fetch arrived with zstd, and the cache-busted fetch with Brotli. This does not establish a compression-specific defect. The startup error happens before React and its error boundary are installed, explaining the lack of an in-app crash panel.
Raw HAR headers were not published because they can contain credentials. The temporary HAR was removed after extracting and verifying the measurements. The malformed bytes remain reproducible from the original complete asset: take its first 832,191 bytes; that prefix reproduces the captured bad SHA-256 exactly. This reconstructs the payload, not the original cache-writing failure.
Healthy origin representations
Fresh HTTP reads of the same asset from the host origin
http://127.0.0.1:38886all completed normally. Each decoded to 1,011,640 bytes and the good SHA-256 above:The host static handler reads the asset into memory and supplies the compressed file length for precompressed responses. These checks rule out a persistently malformed current origin artifact, not a transient failure during the original transfer. The captured failed response headers contained no
Content-Length.Lead for the initiating truncation event
The cached response predates daytime troubleshooting. Host
server.69.logshows a tunnel interruption about 68 seconds after its response timestamp:The wider 00:53–01:04 UTC host log window also contains missed tunnel heartbeats at 00:53:08.093, 00:54:10.654, and 01:00:54.236. At 00:59:04.922 an npm lookup was aborted; at 00:59:05.534 a host lookup failed with
host_unavailable. These support broader instability around the download, without identifying the failing layer. A bounded macOS power-log check found no Sleep/Wake transition in this window; this does not exclude network loss or scheduling stalls.Heartbeat detection runs every 20 seconds with a 60-second acknowledgment deadline (source). Therefore the logged disconnect time is detection time, not a precise timestamp for the first lost byte.
Use the original response timestamp and ray ID to inspect edge logs.
x-bb-cache: missis a stored response header, not proof that every later delivery bypassed all caches; another Cloudflare cache layer can replay it. Host logs do not record byte counts for this asset request: detailed response-size logging is limited to initial thread-load APIs. Cloudflare request logs/runtime traces were unavailable with the investigation’s credentials.Transport and cache source audit: leads, not a proven initiating defect
body-endafter consuming the origin response; an origin read error goes throughclose-stream. The edge closes normally onbody-end, while disconnect handling requests a stream abort. Source inspection did not prove that a disconnect is intentionally converted into successful EOF.body-end; that protocol message carries no byte count or digest. Cloudflare documents that manually set lengths are ignored for arbitrary streaming bodies. Its FixedLengthStream can enforce exact byte counts. This identifies a potential integrity-check improvement, not proof that its absence caused this incident; compression/transcoding boundaries must be handled correctly.cache.putwhile serving the visitor. No application-level asset checksum is checked. The observed incomplete response nevertheless being reusable is proven; which layer treated it as complete is not.Separate native recovery defect
react-native-webview@13.16.1, iOSclearCache(true)includes localStorage, sessionStorage and IndexedDB. However, BB unmounts the WebView on the HTTP error screen, so the optional-ref cache clear then does nothing while cookie clearing still runs. The “Cleared” toast acknowledges command delivery, not completed deletion. Earlier troubleshooting advice that this dependency never clears local storage was incorrect.A further startup-detection limitation: native
onLoadEndmarks the page ready without proving that the app JavaScript mounted. This can fail to surface a bundle startup error, but the native bundle error was not captured here.Recommended recovery direction: await data clearing, reinstall a fresh Connect session before reload, and route page-level 401 through session recovery. Cache clearing must also work without a mounted WebView. Fresh pairing changes the connection identity and should already mint/install a cookie, so its reported failure is not explained solely by the reset defect. Still needed: the native page’s failing URL/status and cookie-presence/validation result, without disclosing token values, plus the native app build.
HTTP 503 recovery limitation
Connect emits HTTP 503 when no open host tunnel is available. Its HTML error page refreshes every ten seconds, but the native app replaces main-frame HTTP errors with its generic panel and unmounts the page, preventing that HTML recovery from running. This is a source-level recovery limitation; the reporter’s uncaptured 503 responses cannot yet be attributed to this specific path.
Originating BB thread (owner access required).
What was ruled out / remains open
__DEV__. The installed app build remains unknown; this explains the expected release-build limitation but does not diagnose its blank screen. macOS Console did not list the phone as an available log source.Remaining investigation and verification
Available incident evidence, source/history, origin representations, publication/deployment records, and bounded host/power logs have been examined. No production restart, cache purge, configuration change, code change, or deliberate connection interruption was performed.
To establish the initiating defect, the next useful work is:
a3bbec720a237c96-EWRand the original timestamp with request outcomes, stream errors, cache status and byte counts if those fields were retained. Historical metadata may be insufficient to recover the original cause.The user's reinstall removed the old native state. Without a new occurrence or reproducible fault injection, identical browser/native truncation cannot be proven retrospectively.
Suggested priority and effort
High: one user lost browser and native access until fresh asset retrieval or reinstall. Access is now recovered; the permanent prevention/recovery fix is still open. Breadth is unknown; no server data loss was reported.