{"record":{"id":"f6ec1718c199d52d","repo":"perspective-dev/perspective","slug":"missing-perspective-client-wasm-f6ec17","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/virtual_servers/clickhouse.ts","lineNumber":263,"sourceCode":"        release();\n    }\n}\n\n/**\n * An implementation of Perspective's Virtual Server for `@duckdb/duckdb-wasm`.\n */\nexport class ClickhouseHandler implements perspective.VirtualServerHandler {\n    private db: clickhouse.ClickHouseClient;\n    private sqlBuilder: perspective.GenericSQLVirtualServerModel;\n    constructor(db: clickhouse.ClickHouseClient, mod?: typeof perspective) {\n        if (!mod) {\n            if (customElements) {\n                const viewer_class: any =\n                    customElements.get(\"perspective-viewer\");\n                if (viewer_class) {\n                    mod = viewer_class.__wasm_module__;\n                } else {\n                    throw new Error(\"Missing perspective-client.wasm\");\n                }\n            } else {\n            }\n        }\n\n        this.db = db;\n        this.sqlBuilder = new mod!.GenericSQLVirtualServerModel({\n            create_entity: \"VIEW\",\n            grouping_fn: \"GROUPING\",\n            column_separator: \"|\",\n            backslash_escaped_literals: true,\n            regex_fn: \"match\",\n        });\n    }\n\n    getFeatures(): perspective.Features {\n        return {\n            group_by: true,","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/perspective-dev/perspective/blob/11c8238c0c9c0b9e490b5a6a2dc277afad1e980a/rust/perspective-js/src/ts/virtual_servers/clickhouse.ts#L245-L281","documentation":"The ClickHouseServer virtual server needs the perspective WebAssembly client module (perspective-client.wasm) to run the database engine in-process. It expects the WASM module to be attached to the registered `<perspective-viewer>` custom element via its `__wasm_module__` property. If the custom element is registered but does not carry the module, the constructor throws this error rather than running without WASM support.","triggerScenarios":"Constructing a ClickHouseServer when `customElements` is available, `customElements.get(\"perspective-viewer\")` returns a registered class, but that class has no `__wasm_module__` property — i.e. the perspective-viewer web component was registered without its WASM assets being loaded/initialized first.","commonSituations":"Loading only the viewer CSS/tag without calling the viewer's init (which fetches and attaches perspective-client.wasm); importing a stub or older/mismatched @finos/perspective-viewer version that doesn't set __wasm_module__; using a custom element registry (e.g. Shadow DOM scoped or overridden registry) where a proxy viewer class is registered; attempting to use the virtual server outside a browser environment or before the WASM bundle finished loading.","solutions":["Ensure @finos/perspective-viewer (and its WASM assets) are fully imported and initialized before creating the ClickHouseServer, so its `__wasm_module__` is set.","Verify the installed @finos/perspective-viewer version matches the perspective-js package version; upgrade/reinstall matching versions.","If not using the viewer component, explicitly fetch perspective-client.wasm and assign it to the viewer class's `__wasm_module__` before constructing the server.","Check that no custom/stub `perspective-viewer` element is registered in `customElements` shadowing the real one."],"exampleFix":"// before\nimport \"@finos/perspective-viewer\"; // component registered, wasm not yet loaded\nconst server = new ClickHouseServer(db);\n\n// after\nimport perspectiveViewer from \"@finos/perspective-viewer\";\nawait perspectiveViewer.init?.(); // ensures perspective-client.wasm is attached as __wasm_module__\nconst server = new ClickHouseServer(db);","handlingStrategy":"validation","validationCode":"function canCreateClickHouseServer() {\n  const viewer = typeof customElements !== \"undefined\" && customElements.get(\"perspective-viewer\");\n  return Boolean(viewer && viewer.__wasm_module__);\n}\nif (!canCreateClickHouseServer()) throw new Error(\"perspective-viewer WASM module not loaded yet\");","typeGuard":"function hasWasmModule(el): el is (typeof el & { __wasm_module__: WebAssembly.Module }) {\n  return typeof el === 'function' && '__wasm_module__' in el && el.__wasm_module__ != null;\n}","tryCatchPattern":"try {\n  const server = new ClickHouseServer(db);\n} catch (e) {\n  if (e.message === \"Missing perspective-client.wasm\") {\n    await initPerspectiveViewer(); // load/attach wasm, then retry\n  } else throw e;\n}","preventionTips":["Always import and await perspective-viewer's initialization before instantiating virtual servers.","Keep @finos/perspective-viewer and perspective-js on the same version.","Add an app-startup assertion that `customElements.get('perspective-viewer').__wasm_module__` exists."],"tags":["webassembly","initialization","custom-elements","clickhouse"],"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"}