Nothing changed in your code. All of a sudden, a tidal wave of errors start happening for Microsoft Edge users. What the heck happened?

On August 28th, 2019, many TrackJS customers saw a sudden surge in errors from Microsoft Edge browsers: Failed to construct 'Request': Invalid Argument and Failed to execute 'fetch()' on 'Window': Invalid argument".

The spark that set off this error was a change in the Facebook sdk. Specifically, this snippet of code from their sdk.js:

fetch(url, {
    referrerPolicy:"origin",
    mode:"cors",
    credentials:"include"
});
Code snippet adapted from https://connect.facebook.net/en_US/sdk.js

In this of call to fetch, facebook is passing referrerPolicy. However, as noted in the compatibility table, the referrerPolicy has “No Support” on Microsoft Edge.

“No Support” is an understatement.

Root Cause

fetch can be called with a Request object. However, all known versions of Microsoft Edge, through 18.18975, this will throw an error if referrerPolicy is passed as an option.

For example, this snippet of code will throw an error in Edge:

var req = new Request("https://example.com/", {
    referrerPolicy: "origin"
});
Code snippet that breaks Microsoft Edge

Failed to construct 'Request': Invalid Argument.

The referrerPolicy property was added to the standard in June 2018, so it is understandable that Edge does not yet support it. However, the fact that Edge throws indicates that Microsoft’s implementation of Request is leaking out.

We have opened an issue with Microsoft about this issue. However, as they will soon be switching to the Chromium engine, we expect it to go unresolved.

This bug may also manifest as the error Failed to execute 'fetch()' on 'Window': Invalid argument. if you pass the referrerKey option to fetch directly. This error will not be thrown, however, it will come as a Promise rejection.

Workaround

ReferrerPolicy specifies whether the current URL will be provided on the Referer header for the request. MDN has some great examples of how this will be applied.

While Facebook will need to resolve the issue on their sdk, you may still have this error in your own code. Fortunately, the most common use cases for the policy can still be achieved.


Option #1: Don’t Use Request

The issue only manifests itself using the Request object as an argument to fetch. You can pass the same parameters directly the fetch. For example,

fetch(new Request('/', {/*options*/})) // becomes fetch('/', {/*options*/})

Option #2: Use Default referrerPolicy

Simply don’t set the referrerPolicy for the request. This will default to the page’s policy and send along appropriate information. You will need to set the referrerPolicy header appropriate when serving your web pages.


Option #3: Explicit Set Referrer

Rather than relying on the policy to decide what to send as the origin value, you can control how much information is passed along with the referrer property.

For example, if you want to replicate the "origin" referrerPolicy, you can use the following code to strip path information out of the referrer by setting it to the root of your domain.

fetch("https://example.com/", {
    referrer: "/"
});
Replicate Origin ReferrerPolicy

Another example, if you want to replicate the "no-referrer" referrerPolicy, you can remove the referrer all together by setting it to empty string.

fetch("https://example.com/", {
    referrer: ""
});
Replicate Origin ReferrerPolicy

Browsers and third-parties can create errors on your website when you least expect them. Production error monitoring from TrackJS will let you know when someone breaks your site. Give it a try and let’s build a better web, together.