GraphiteEditor/Graphite · error
Function call failed
Error message
Function call failed
What it means
After resolving initializeNativeCommunication, the wrapper invokes it with func.call0 and expects success. This panic means the JS function was found and called but its body threw: the bridge exists, yet its internals failed — usually because the native APIs it wraps are unavailable or not ready at call time.
Source
Thrown at frontend/wrapper/src/native_communication.rs:83
pub fn decode_editor_command(data: &[u8]) -> Option<editor::messages::prelude::Message> {
match serde_json::from_slice::<crate::EditorCommand>(data) {
Ok(command) => Some(command.into()),
Err(e) => {
log::error!("Failed to deserialize editor command: {e}");
None
}
}
}
pub fn initialize_native_communication() {
let global = js_sys::global();
// Get the function by name
let func = js_sys::Reflect::get(&global, &JsValue::from_str("initializeNativeCommunication")).expect("Function not found");
let func = func.dyn_into::<js_sys::Function>().expect("Not a function");
// Call it
func.call0(&JsValue::NULL).expect("Function call failed");
}
pub fn send_message_to_cef(message: String) {
let global = js_sys::global();
// Get the function by name
let func = js_sys::Reflect::get(&global, &JsValue::from_str("sendNativeMessage")).expect("Function not found");
let func = func.dyn_into::<js_sys::Function>().expect("Not a function");
let array = Uint8Array::from(message.as_bytes());
let buffer = array.buffer();
// Call it with argument
func.call1(&JsValue::NULL, &JsValue::from(buffer)).expect("Function call failed");
}
#[cfg(feature = "editor")]
pub(crate) use editor::messages::frontend::utility_types::RasterizedImage;View on GitHub (pinned to c507b35645)
Solutions
- Open the browser/CEF console and read the underlying JS exception and stack before the Rust panic obscures it
- Make the JS-side bridge idempotent and defensive so double init or missing natives degrade to a log line
- Handle the Result from call0: log the error and continue startup instead of panicking
Example fix
// before
func.call0(&JsValue::NULL).expect("Function call failed");
// after
if let Err(e) = func.call0(&JsValue::NULL) {
error!("initializeNativeCommunication threw: {:?}", e);
} Defensive patterns
Strategy: try-catch
Try / catch
if let Err(e) = func.call0(&JsValue::NULL) {
error!("initializeNativeCommunication threw: {:?}", e);
} Prevention
- Initialize the native side fully before loading the editor wasm
- Wrap bridge function bodies in try/catch on the JS side and expose a readiness flag
- Keep wrapper and native shell versions in lockstep to avoid throwing bridge internals
When it happens
Trigger: Calling the bridge before the CEF-side native bindings it uses are registered; the function throwing when executed outside its expected host; duplicate initialization hitting a throw-on-second-call path.
Common situations: Startup races between wasm start and native host initialization; version mismatch between the wrapper and the native shell; running the bridge in a browser where its internals reference CEF-only objects.
Related errors
- Function not found
- Not a function
- Failed to spawn the CEF control thread
- The CEF control thread ended without a result
- Failed to connect to the main process bootstrap server
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/50c3aa7e36b2f1ba.
Report an issue: GitHub.