golang/go · critical · Error
globalThis.performance is not available, polyfill required (
Error message
globalThis.performance is not available, polyfill required (performance.now only)
What it means
Thrown by wasm_exec.js when globalThis.performance is absent at load time. The Go wasm runtime uses performance.now() for its clock source (timers, runtime.nanotime). This is a startup self-check that fires before any Go code runs, so the failure is always at module evaluation, not later.
Source
Thrown at lib/wasm/wasm_exec.js:89
cwd() { throw enosys(); },
chdir() { throw enosys(); },
}
}
if (!globalThis.path) {
globalThis.path = {
resolve(...pathSegments) {
return pathSegments.join("/");
}
}
}
if (!globalThis.crypto) {
throw new Error("globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)");
}
if (!globalThis.performance) {
throw new Error("globalThis.performance is not available, polyfill required (performance.now only)");
}
if (!globalThis.TextEncoder) {
throw new Error("globalThis.TextEncoder is not available, polyfill required");
}
if (!globalThis.TextDecoder) {
throw new Error("globalThis.TextDecoder is not available, polyfill required");
}
const encoder = new TextEncoder("utf-8");
const decoder = new TextDecoder("utf-8");
globalThis.Go = class {
constructor() {
this.argv = ["js"];
this.env = {};
this.exit = (code) => {View on GitHub (pinned to b6b368adc5)
Solutions
- Use Node.js >= 8, where globalThis.performance is available.
- Polyfill before loading wasm_exec.js: const { performance } = require('node:perf_hooks'); globalThis.performance = performance;
- Minimal fallback: globalThis.performance = { now: () => Date.now() }; (lower resolution, acceptable for non-benchmarking use).
- If using a VM context, inject performance explicitly via the contextified sandbox object.
Example fix
// before
require('./wasm_exec.js'); // throws: globalThis.performance is not available
// after
const { performance } = require('node:perf_hooks');
globalThis.performance = performance;
require('./wasm_exec.js'); Defensive patterns
Strategy: validation
Validate before calling
if (typeof globalThis.performance === 'undefined' || typeof globalThis.performance.now !== 'function') {
const { performance } = require('node:perf_hooks');
globalThis.performance = performance;
} Type guard
const hasPerformance = () => typeof globalThis.performance === 'object' && globalThis.performance !== null && typeof globalThis.performance.now === 'function';
Prevention
- Run on Node >= 8 (performance is global).
- Keep a bootstrap module that polyfills performance before wasm_exec.js is required.
- For vm contexts, inject performance explicitly into the contextified sandbox.
When it happens
Trigger: Loading wasm_exec.js in a JS engine with no High Resolution Time API: QuickJS without the perf module, very old Node (< 8), a `vm.createContext` that did not copy performance, or a minimal embedded runtime.
Common situations: Bundling Go wasm for a non-browser target and forgetting to polyfill timing; running tests in a sandboxed JS interpreter; migrating a Go-wasm worker from browser (which has performance) to a minimal Node script (older versions).
Related errors
- globalThis.crypto is not available, polyfill required (crypt
- globalThis.TextEncoder is not available, polyfill required
- globalThis.TextDecoder is not available, polyfill required
- Go.run: WebAssembly.Instance expected
- total length of command line and environment variables excee
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/afaa0821f0536cfa.
Report an issue: GitHub.