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
- Upgrade the runtime (Node/bundler output) to one with globalThis.URL available (Node >= 10, modern browsers)
- Add a URL polyfill to globalThis before the Glimmer runtime initializes
- Ensure bundler/polyfill config does not strip or stub globalThis.URL
- 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
- Polyfill globalThis.URL early in SSR/embedded entry points
- Target runtimes with URL support (Node >= 10, modern browsers)
- Audit bundler polyfills/stubs that remove URL from globals
- Smoke-test rendering in the target environment in CI
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
- Attempted to cast to a browser node in a non-browser context
- you must pass document or appendOperations to a new runtime
- Rehydration with nextSibling not supported
- Compile Error: ${template.problem} @ ${template.span.start}.
- A resolved helper cannot be passed as a named argument as th
AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01).
Data as JSON: /api/errors/ff5626bddcb61020.
Report an issue: GitHub.