Skip to content

Vitest v4 + JSDOM: URL.createObjectUrl fails due to mismatching Blob constructors #8917

@fpapado

Description

@fpapado

Describe the bug

When using Vitest V4 (4.0.6) with JSDOM (both 26 and 27, that I checked), the following code throws:

/// @vitest-environment jsdom
import { describe, it, expect } from "vitest";

describe("createObjectUrl", () => {
  it("constructs URL (if present)", async () => {
    expect(() => {
      if (URL.createObjectURL !== undefined) {
        URL.createObjectURL(new Blob());
      }
    }).not.toThrow();
  });
});
FAIL  blob-url-jsdom.spec.ts > createObjectUrl > constructs URL (if present)
AssertionError: expected [Function] to not throw an error but 'TypeError [ERR_INVALID_ARG_TYPE]: The…' was thrown

- Expected:
undefined

+ Received:
"TypeError [ERR_INVALID_ARG_TYPE]: The \"obj\" argument must be an instance of Blob. Received an instance of Blob"

 ❯ blob-url-jsdom.spec.ts:10:12
      8|         URL.createObjectURL(new Blob());
      9|       }
     10|     }).not.toThrow();
       |            ^
     11|   });
     12| });

In our repository, this code comes from a dependency, which checks for URL.createObjectURL and calls it conditionally. In v3, where URL.createObjectURL is not defined in a JSDOM environment, this is ok.

What I believe happens here, is that the Blob constructor is mismatching, between the node global (from node:buffer) and what JSDOM provides. I think ultimately it is the node URL.createObjectUrl that gets used, but with the JSDOM Blob.

For example, if I stub the global Blob to use the node Blob directly:

import { Blob as NodeBlob } from 'node:buffer';

vi.stubGlobal('Blob', NodeBlob);

...tests seem to pass again.

Reproduction

In addition to the example above, I have a reproduction at https://github.com/fpapado/vitest-v4-jsdom-blob-and-create-object-url, with JSDOM, happy-dom and Node environments. Of the three, only JSDOM fails.

System Info

System:
    OS: macOS 15.6.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 108.50 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 24.11.0 - /Users/fotis/.local/state/fnm_multishells/42777_1762175329180/bin/node
    npm: 11.6.1 - /Users/fotis/.local/state/fnm_multishells/42777_1762175329180/bin/npm
    pnpm: 10.15.0 - /Users/fotis/.local/state/fnm_multishells/42777_1762175329180/bin/pnpm
  Browsers:
    Chrome: 141.0.7390.123
    Chrome Canary: 144.0.7505.0
    Firefox: 144.0.2
    Firefox Developer Edition: 145.0
    Safari: 26.0.1
    Safari Technology Preview: 26.0
  npmPackages:
    vitest: 4.0.6 => 4.0.6

Used Package Manager

pnpm

Validations

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions