emberjs/ember.js · critical · Error

@glimmer/runtime needs a valid "globalThis.URL"

Error message

@glimmer/runtime needs a valid "globalThis.URL"

What it means

protocolForUrl sanitizes URLs (for href/src attributes) by parsing them with globalThis.URL to extract the protocol and block dangerous protocols like javascript:. If the runtime environment does not provide a usable globalThis.URL constructor, Glimmer cannot sanitize URLs and throws this error at implementation setup time instead of proceeding unsafely.

Source

Thrown at packages/@glimmer/runtime/lib/dom/sanitized-values.ts:113

      return protocol === null ? ':' : protocol;
    };
  } else if (typeof weirdURL === 'function') {
    return (_url: string) => {
      try {
        let url = new weirdURL(_url);

        return url.protocol;
      } catch {
        // any non-fully qualified url string will trigger an error (because there is no
        // baseURI that we can provide; in that case we **know** that the protocol is
        // "safe" because it isn't specifically one of the `badProtocols` listed above
        // (and those protocols can never be the default baseURI)
        return ':';
      }
    };
  } else {
    throw new Error(`@glimmer/runtime needs a valid "globalThis.URL"`);
  }
}

let _protocolForUrlImplementation: typeof protocolForUrl | undefined;
function protocolForUrl(url: string): string {
  if (!_protocolForUrlImplementation) {
    _protocolForUrlImplementation = findProtocolForURL();
  }
  return _protocolForUrlImplementation(url);
}

export function sanitizeAttributeValue(
  element: SimpleElement,
  attribute: string,
  value: unknown
): unknown {
  if (value === null || value === undefined) {
    return value;

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Upgrade the runtime (Node/bundler output) to one with globalThis.URL available (Node >= 10, modern browsers)
  2. Add a URL polyfill to globalThis before the Glimmer runtime initializes
  3. Ensure bundler/polyfill config does not strip or stub globalThis.URL
  4. Verify globalThis.URL works at app startup (typeof globalThis.URL === 'function')

Example fix

// before
// no URL global in the environment
// after
import { URL } from 'whatwg-url';
if (typeof globalThis.URL !== 'function') {
  globalThis.URL = URL;
}
Defensive patterns

Strategy: validation

Validate before calling

if (typeof globalThis !== 'object' || typeof globalThis.URL !== 'function') {
  throw new Error('globalThis.URL is required before initializing the Glimmer runtime');
}

Type guard

function hasUrlGlobal(env: unknown = globalThis): env is typeof globalThis & { URL: URLConstructor } {
  return typeof (env as any)?.URL === 'function';
}

Try / catch

try {
  renderTemplate(...);
} catch (e) {
  if (String(e?.message).includes('globalThis.URL')) {
    installUrlPolyfill(); // then retry or fail fast with a clear message
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling protocolForUrl (indirectly via findProtocolForURL during attribute sanitization) in an environment where globalThis or globalThis.URL is undefined or not a valid constructor — e.g. very old runtimes, stripped/minified Node builds, or unusual embedded JS engines.

Common situations: SSR/Node versions without global URL (Node < 10); bundler polyfill shims that delete or stub globalThis.URL; restricted environments (some embedded engines, older JSDOM setups) lacking the URL global.

Related errors


AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01). Data as JSON: /api/errors/ff5626bddcb61020. Report an issue: GitHub.