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

  1. Open the browser/CEF console and read the underlying JS exception and stack before the Rust panic obscures it
  2. Make the JS-side bridge idempotent and defensive so double init or missing natives degrade to a log line
  3. 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

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


AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16). Data as JSON: /api/errors/50c3aa7e36b2f1ba. Report an issue: GitHub.