{"record":{"id":"bc3d8b0537de7eed","repo":"GraphiteEditor/Graphite","slug":"not-a-function","errorCode":null,"errorMessage":"Not a function","messagePattern":"Not a function","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/wrapper/src/native_communication.rs","lineNumber":92,"sourceCode":"\npub fn initialize_native_communication() {\n\tlet global = js_sys::global();\n\n\t// Get the function by name\n\tlet func = js_sys::Reflect::get(&global, &JsValue::from_str(\"initializeNativeCommunication\")).expect(\"Function not found\");\n\tlet func = func.dyn_into::<js_sys::Function>().expect(\"Not a function\");\n\n\t// Call it\n\tfunc.call0(&JsValue::NULL).expect(\"Function call failed\");\n}\n\npub fn send_message_to_cef(message: String) {\n\tlet global = js_sys::global();\n\n\t// Get the function by name\n\tlet func = js_sys::Reflect::get(&global, &JsValue::from_str(\"sendNativeMessage\")).expect(\"Function not found\");\n\n\tlet func = func.dyn_into::<js_sys::Function>().expect(\"Not a function\");\n\tlet array = Uint8Array::from(message.as_bytes());\n\tlet buffer = array.buffer();\n\n\t// Call it with argument\n\tfunc.call1(&JsValue::NULL, &JsValue::from(buffer)).expect(\"Function call failed\");\n}\n\n#[cfg(feature = \"editor\")]\npub(crate) use editor::messages::frontend::utility_types::RasterizedImage;\n\n#[cfg(not(feature = \"editor\"))]\npub(crate) use RasterizedImageCopy as RasterizedImage;\n\n#[cfg(any(not(feature = \"editor\"), test))]\n#[derive(serde::Deserialize)]\npub(crate) struct RasterizedImageCopy {\n\tpub(crate) id: u64,\n\tpub(crate) width: u32,","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/frontend/wrapper/src/native_communication.rs#L74-L110","documentation":"The wrapper found a property named sendNativeMessage on the JS global, but dyn_into::<js_sys::Function>() failed because the value is not callable. Existence and callability are separate checks in this code, and this panic is the second one failing: the name is occupied by a non-function value.","triggerScenarios":"Another script defining window.sendNativeMessage as non-function data (name collision); a placeholder or stub object assigned before the real function loads; a partially initialized bridge leaving a module object instead of a function.","commonSituations":"Page scripts, analytics, or bundler shims claiming generic global names; older bridge versions assigning state objects; third-party code on the same page in the CEF shell.","solutions":["Inspect typeof window.sendNativeMessage in the failing page to see what occupies the name","Use dyn_ref::<Function>() and log the actual type before calling","Namespace the bridge globals (for example __graphiteSendNativeMessage) so page scripts cannot collide"],"exampleFix":"// before\nlet func = func.dyn_into::<js_sys::Function>().expect(\"Not a function\");\n\n// after\nlet Some(func) = found.dyn_ref::<js_sys::Function>().cloned() else {\n\terror!(\"sendNativeMessage has unexpected type: {:?}\", found.js_typeof());\n\treturn;\n};","handlingStrategy":"type-guard","validationCode":"// host page: assert the name is actually a function before the wasm sends\n// console.assert(typeof window.sendNativeMessage === 'function')","typeGuard":"fn as_function(value: &JsValue) -> Option<js_sys::Function> {\n\tvalue.dyn_ref::<js_sys::Function>().cloned()\n}","tryCatchPattern":null,"preventionTips":["Namespace bridge globals so page scripts cannot shadow them","Check js_typeof before every dyn_into on host-provided values","Assign bridge functions in one atomic script load rather than progressive stubbing"],"tags":["cef","js-interop","dyn-into","globalthis"],"backgroundTag":"wasm-bindgen-type-cast-failed","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}