{"record":{"id":"c0fa73e9d16e9adf","repo":"perspective-dev/perspective","slug":"missing-perspective-client-wasm","errorCode":null,"errorMessage":"Missing perspective-client.wasm","messagePattern":"Missing perspective-client\\.wasm","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"rust/perspective-js/src/ts/perspective.browser.ts","lineNumber":285,"sourceCode":"    } else if (wasm instanceof Object) {\n        GLOBAL_CLIENT_WASM = Promise.resolve(wasm as typeof psp);\n    }\n}\n\nfunction get_client() {\n    const viewer_class: any = customElements.get(\"perspective-viewer\");\n    if (viewer_class) {\n        GLOBAL_CLIENT_WASM = Promise.resolve(viewer_class.__wasm_module__);\n        if (\n            GLOBAL_CLIENT_MODULE === undefined &&\n            viewer_class.__wasm_client_module__\n        ) {\n            GLOBAL_CLIENT_MODULE = Promise.resolve(\n                viewer_class.__wasm_client_module__,\n            );\n        }\n    } else if (GLOBAL_CLIENT_WASM === undefined) {\n        throw new Error(\"Missing perspective-client.wasm\");\n    }\n\n    return GLOBAL_CLIENT_WASM;\n}\n\n/**\n * Returns the compiled `WebAssembly.Module` for the perspective-js client\n * runtime. The module is structured-cloneable, so it can be sent via\n * `postMessage` to a Worker which can instantiate its own `Client` without\n * re-fetching or re-compiling the wasm binary.\n *\n * Requires that the client wasm has been initialized — typically by a prior\n * call to `init_client(...)`, or implicitly by mounting a `<perspective-viewer>`\n * element. Throws otherwise.\n *\n * # Examples\n *\n * ```javascript","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/perspective-dev/perspective/blob/11c8238c0c9c0b9e490b5a6a2dc277afad1e980a/rust/perspective-js/src/ts/perspective.browser.ts#L267-L303","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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()`.","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."],"exampleFix":"// before\nconst worker = perspective.worker(); // throws: no wasm initialized\n// after\nawait perspective.init_client(fetch(\"perspective-client.wasm\"));\nconst worker = perspective.worker();","handlingStrategy":"try-catch","validationCode":"const viewerDefined = !!customElements.get(\"perspective-viewer\");\nconst clientReady = viewerDefined || clientWasmInitialized; // track your own init flag\nif (!clientReady) await perspective.init_client(fetch(\"perspective-client.wasm\"));","typeGuard":"function clientWasmAvailable(): boolean {\n  return !!customElements.get(\"perspective-viewer\") || clientWasmInitialized;\n}","tryCatchPattern":"let worker;\ntry {\n  worker = perspective.worker();\n} catch (e) {\n  if (String(e.message).includes(\"Missing perspective-client.wasm\")) {\n    await perspective.init_client(fetch(\"perspective-client.wasm\"));\n    worker = perspective.worker();\n  } else throw e;\n}","preventionTips":["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."],"tags":["wasm","initialization","browser","missing-asset"],"backgroundTag":"module-init-failed","analyzedSha":"11c8238c0c9c0b9e490b5a6a2dc277afad1e980a","analyzedAt":"2026-09-09T00:35:19.377Z","contentChangedAt":"2026-09-09T00:35:19.377Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}