perspective-dev/perspective · error · Error
Missing perspective-client.wasm
Error message
Missing perspective-client.wasm
What it means
`get_client()` resolves the client wasm used to create Perspective clients. It first checks whether a `<perspective-viewer>` custom element is registered (whose wasm can be reused); otherwise it relies on the global set by `init_client()`. If neither exists, the browser build has no client wasm available and throws "Missing perspective-client.wasm" — typically because `worker()`/`websocket()`/`createMessageHandler()` was called before any wasm was initialized.
Solutions
- Call `perspective.init_client(fetch('perspective-client.wasm'))` (or pass an ArrayBuffer/Response/initialized module) before creating workers or connections.
- Import/define the `<perspective-viewer>` custom element so its wasm can be reused, if your setup loads wasm through the viewer.
- If using a bundler, ensure the wasm plugin/asset pipeline includes perspective-client.wasm and the default init path isn't tree-shaken.
- Ensure the call happens after init, not at module-evaluation top level before init completes.
Example fix
// before
const worker = perspective.worker(); // throws: no wasm initialized
// after
await perspective.init_client(fetch("perspective-client.wasm"));
const worker = perspective.worker(); Defensive patterns
Strategy: try-catch
Validate before calling
const viewerDefined = !!customElements.get("perspective-viewer");
const clientReady = viewerDefined || clientWasmInitialized; // track your own init flag
if (!clientReady) await perspective.init_client(fetch("perspective-client.wasm")); Type guard
function clientWasmAvailable(): boolean {
return !!customElements.get("perspective-viewer") || clientWasmInitialized;
} Try / catch
let worker;
try {
worker = perspective.worker();
} catch (e) {
if (String(e.message).includes("Missing perspective-client.wasm")) {
await perspective.init_client(fetch("perspective-client.wasm"));
worker = perspective.worker();
} else throw e;
} Prevention
- Always run an explicit `init_client(...)` in bootstrap before creating workers/connections.
- Never call `perspective.worker()` at module top level; await init first.
- Verify your bundler includes perspective-client.wasm in the output.
- Import and register the perspective-viewer custom element if you depend on its wasm reuse.
When it happens
Trigger: Calling `perspective.worker()`, `perspective.websocket(url)`, or `createMessageHandler()` in a page where `init_client(...)` was never called and no `<perspective-viewer>` element is registered. Also when the viewer custom element has not been upgraded/imported at the time of the call.
Common situations: Bundlers not wiring the default wasm import (tree-shaken or misconfigured wasm plugin); calling `perspective.worker()` at module top level before init code runs; forgetting to import the perspective-viewer package in apps that only use the client API; upgrading to a version where implicit wasm loading was removed in favor of explicit `init_client()`.
Related errors
- init_server requires a wasm source or a
- Missing perspective-server.wasm
- perspective-js client wasm has not been compiled yet — call…
- data script missing for viewer
- Failed to fetch perspective server wasm
AI-assisted analysis of perspective-dev/perspective@11c8238c0c (2026-09-09).
Data as JSON: /api/errors/c0fa73e9d16e9adf.
Report an issue: GitHub.
Appendix: source
Thrown at rust/perspective-js/src/ts/perspective.browser.ts:285
} else if (wasm instanceof Object) {
GLOBAL_CLIENT_WASM = Promise.resolve(wasm as typeof psp);
}
}
function get_client() {
const viewer_class: any = customElements.get("perspective-viewer");
if (viewer_class) {
GLOBAL_CLIENT_WASM = Promise.resolve(viewer_class.__wasm_module__);
if (
GLOBAL_CLIENT_MODULE === undefined &&
viewer_class.__wasm_client_module__
) {
GLOBAL_CLIENT_MODULE = Promise.resolve(
viewer_class.__wasm_client_module__,
);
}
} else if (GLOBAL_CLIENT_WASM === undefined) {
throw new Error("Missing perspective-client.wasm");
}
return GLOBAL_CLIENT_WASM;
}
/**
* Returns the compiled `WebAssembly.Module` for the perspective-js client
* runtime. The module is structured-cloneable, so it can be sent via
* `postMessage` to a Worker which can instantiate its own `Client` without
* re-fetching or re-compiling the wasm binary.
*
* Requires that the client wasm has been initialized — typically by a prior
* call to `init_client(...)`, or implicitly by mounting a `<perspective-viewer>`
* element. Throws otherwise.
*
* # Examples
*
* ```javascriptView on GitHub (pinned to 11c8238c0c)