perspective-dev/perspective · error · Error

Missing perspective-server.wasm

Error message

Missing perspective-server.wasm

What it means

`get_server()` (used by `worker()`) materializes the server wasm that backs the Perspective engine in the Worker. It requires that `init_server()` was previously called to populate `SERVER_REGISTRY`; if not, there is no server wasm binary to select or download and it throws "Missing perspective-server.wasm".

Solutions

  1. Call `perspective.init_server(fetch('perspective-server.wasm'))` before `perspective.worker()`.
  2. For Memory64 hosts use the registration form: `init_server({ wasm32: () => fetch('perspective-server.wasm'), wasm64: () => fetch('perspective-server.memory64.wasm') })`.
  3. Ensure the server wasm asset is emitted by your bundler and the fetch URL resolves (check network tab for 404s).
  4. Order bootstrap so `init_server(...)` runs to completion before any `worker()` call.

Example fix

// before
const worker = perspective.worker(); // throws: no server wasm registered
// after
perspective.init_server(fetch("perspective-server.wasm"));
const worker = perspective.worker();
Defensive patterns

Strategy: try-catch

Validate before calling

if (!serverInitialized) {
  perspective.init_server(fetch("perspective-server.wasm"));
}
const worker = perspective.worker();

Type guard

function serverWasmRegistered(): boolean {
  return serverInitialized; // set true immediately after init_server(...) succeeds
}

Try / catch

try {
  const worker = perspective.worker();
} catch (e) {
  if (String(e.message).includes("Missing perspective-server.wasm")) {
    perspective.init_server(fetch("perspective-server.wasm"));
    const worker = perspective.worker();
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `perspective.worker()` (the only caller) in a page where `perspective.init_server(...)` was never invoked — e.g. relying on a Node-style auto-load that doesn't exist in the browser build, or calling `worker()` before init.

Common situations: Upgrading perspective-js to a version that requires explicit `init_server()` registration in the browser; bundler not emitting/copying perspective-server.wasm so init code is skipped; calling `worker()` at module top level before the init call runs; forgetting the init call after refactoring bootstrap code.

Related errors


AI-assisted analysis of perspective-dev/perspective@11c8238c0c (2026-09-09). Data as JSON: /api/errors/4eabd6d1ca0f13f6. Report an issue: GitHub.

Appendix: source

Thrown at rust/perspective-js/src/ts/perspective.browser.ts:330

    const viewer_class: any = customElements.get("perspective-viewer");
    if (viewer_class?.__wasm_client_module__) {
        GLOBAL_CLIENT_MODULE = Promise.resolve(
            viewer_class.__wasm_client_module__,
        );
        return GLOBAL_CLIENT_MODULE;
    }

    throw new Error(
        "perspective-js client wasm has not been compiled yet — call " +
            "`init_client(...)` or `perspective.worker()` before " +
            "`getCompiledClientWasm()`.",
    );
}

function get_server() {
    if (SERVER_REGISTRY === undefined) {
        throw new Error("Missing perspective-server.wasm");
    }

    if (GLOBAL_SERVER_WASM === undefined) {
        GLOBAL_SERVER_WASM = select_server_wasm(SERVER_REGISTRY);
    }

    return GLOBAL_SERVER_WASM.then((x) =>
        x instanceof WebAssembly.Module ? x : x.slice(0),
    );
}

let GLOBAL_WORKER: undefined | (() => Promise<Worker>) = undefined;

// `WorkerPlugin` resolves this import to a stub that exports
// `getPerspectiveWorkerURL(): Promise<string>`. The URL is either a
// Blob URL (inline mode — production builds) or a real file path
// resolved against `import.meta.url` (file mode — debug builds).
// Constructing the `Worker` lives here in the consumer rather than

View on GitHub (pinned to 11c8238c0c)