Bug Report: `fetch()` crashes with "Request is not a constructor" in Checkout UI Extension

Extensions

In a Checkout UI Extension with network_access = true, calling the global fetch() function causes the following runtime error:

Uncaught (in promise) TypeError: Request is not a constructor

This issue occurs even when generating the extension using the candidate version of the CLI:

POLARIS_UNIFIED=true shopify app generate extension

Expected Behavior

Since network_access = true is enabled in the extension config, fetch() should work for making external network requests.
Also, typeof Request === "function" and new Request(...) works outside the fetch() implementation, so this constructor should be valid in the runtime.


Actual Behavior

Calling fetch() causes a runtime crash with TypeError: Request is not a constructor.

The decompiled internal source of Shopify’s fetch() implementation contains:

const v = new Request(s, u); // ← causes the crash

This assumes that Request is a working native constructor — but in the extension runtime, although typeof Request === "function", it is not actually constructible inside fetch().


Steps to Reproduce

  1. Create a basic Checkout UI Extension using Shopify CLI (candidate version):

    POLARIS_UNIFIED=true shopify app generate extension
    
  2. Set the following in shopify.extension.toml:

    network_access = true
    
  3. Add the following code to your extension:

    const testFetch = async () => {
      try {
        const res = await fetch("https://httpbin.org/post", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ test: true }),
        });
        const json = await res.json();
        console.log("✅ Success:", json);
      } catch (e) {
        console.error("❌ fetch failed:", e);
      }
    };
    testFetch();
    
  4. Preview or deploy the extension

  5. View the browser console

:collision: Expected result: Success response from httpbin
:cross_mark: Actual result:

TypeError: Request is not a constructor

Diagnostics

  • :white_check_mark: typeof Request === "function"
  • :white_check_mark: new Request("https://example.com") works outside fetch()
  • :cross_mark: fetch() internally calls new Request(...), which fails at runtime
  • :white_check_mark: No cross-fetch, graphql-request, or fetch polyfill is included
  • :white_check_mark: dist/ output confirms Request is not bundled manually

Environment

Key Value
Shopify CLI 3.82.1
Node.js v20.11.1
Extension Runtime Checkout UI Extension
network_access true
Browser Chrome

Suggested Fix

Please either:

  • Update the fetch() implementation in the runtime to not rely on new Request(...), or
  • Ensure the Request constructor in the sandbox environment is valid and constructible

Additional Notes

  • This issue appears even in a completely clean extension with minimal dependencies
  • fetch() is promoted as usable when network_access = true, so this behavior is unexpected
  • The runtime polyfill may be internally broken or partially defined

Thanks in advance for looking into this!

I’m also experiencing this problem unfortunately

@tokujirou @mjphaynes Did you find a solution?