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
Cuprite url_blacklist (Fetch interception) can hang XHR PUT with Blob body (Rails ActiveStorage direct uploads) #308
As a result of an upgrade from Rails 7.2 to 8.0, we started having issues with ActiveStorage direct uploads hanging on the upload PUT request to /rails/active_storage/disk/....
The preceding POST to /rails/active_storage/direct_uploads succeeds (200), but the subsequent PUT never finishes; Chrome DevTools shows the request stuck with “Provisional headers are shown”.
Disabling url_blacklist fixes it. As a workaround, we can still block external resources using CDP Network.setBlockedURLs, which does not hang the upload.
The PUT hangs in both headless and headed mode.
Configure Cuprite with url_blacklist to block external assets (e.g. google.com, googleapis.com).
Visit a page that triggers an ActiveStorage direct upload.
Attach a file (direct upload kicks off).
Observe: POST /rails/active_storage/direct_uploads completes, but PUT /rails/active_storage/disk/<signed_id> hangs indefinitely (DevTools shows “Provisional headers are shown”; system tests time out).
Expected:
The direct-upload PUT completes and the file attaches.
Actual:
The direct-upload PUT never completes; UI/test remains stuck.
Workaround:
Avoid Cuprite url_blacklist and instead block external requests via CDP:
url_blacklist appears to enable CDP Fetch request interception. Once interception is enabled, uploads using binary/streaming bodies (XHR/fetch PUT Blob) can stall, even though the request URL itself is not blacklisted (same-origin ActiveStorage disk upload route).
With url_blacklist, Ferrum pauses every request until it continues or aborts it. For a Blob body, such as the file.slice() that Rails 8's ActiveStorage direct upload sends, Chrome includes the raw bytes in the paused event, and some byte sequences come out as lone UTF-16 surrogates. The json gem rejected the message, Ferrum dropped it and never continued the request, so the PUT hung with "Provisional headers are shown". Lone surrogates are now replaced instead, and the upload completes with url_blacklist on. Until the release, your Network.setBlockedURLs workaround keeps working, since it doesn't pause requests.
Activity
fix(client): replace lone UTF-16 surrogates instead of dropping the m…
route commentedon Oct 16, 2026
Fixed in rubycdp/ferrum#648, which ships in the next Ferrum release.
With
url_blacklist, Ferrum pauses every request until it continues or aborts it. For aBlobbody, such as thefile.slice()that Rails 8's ActiveStorage direct upload sends, Chrome includes the raw bytes in the paused event, and some byte sequences come out as lone UTF-16 surrogates. Thejsongem rejected the message, Ferrum dropped it and never continued the request, so the PUT hung with "Provisional headers are shown". Lone surrogates are now replaced instead, and the upload completes withurl_blackliston. Until the release, yourNetwork.setBlockedURLsworkaround keeps working, since it doesn't pause requests.