{"record":{"id":"db16cc5188344a4a","repo":"GraphiteEditor/Graphite","slug":"failed-to-send-hello-to-the-main-process","errorCode":null,"errorMessage":"Failed to send Hello to the main process","messagePattern":"Failed to send Hello to the main process","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"desktop/ui/src/remote/host.rs","lineNumber":53,"sourceCode":"\t#[cfg(feature = \"accelerated_paint\")]\n\tlet acceleration = plane.is_some();\n\t#[cfg(not(feature = \"accelerated_paint\"))]\n\tlet acceleration = {\n\t\tif acceleration_requested {\n\t\t\ttracing::error!(\"UI acceleration requested but the accelerated_paint feature is disabled; using software frames\");\n\t\t}\n\t\tfalse\n\t};\n\n\tevent_sender\n\t\t.lock()\n\t\t.expect(\"The host message sender cannot be poisoned before threads exist\")\n\t\t.send(EventMessage::Hello {\n\t\t\tpid: std::process::id(),\n\t\t\tcontrol_sender,\n\t\t\tacceleration,\n\t\t})\n\t\t.expect(\"Failed to send Hello to the main process\");\n\n\tlet sequence = Arc::new(SequenceState::new());\n\tlet frames = FrameStreamer::new(\n\t\tevent_sender.clone(),\n\t\tsequence.clone(),\n\t\t#[cfg(feature = \"accelerated_paint\")]\n\t\tplane,\n\t);\n\tlet (view_info_sender, view_info_receiver) = std::sync::mpsc::channel();\n\tlet delegate = BrowserDelegate::new(event_sender.clone(), view_info_receiver);\n\n\tlet context = match CefContext::create(delegate, frames, view_info_sender, acceleration) {\n\t\tOk(context) => {\n\t\t\tif let Ok(sender) = event_sender.lock() {\n\t\t\t\tlet _ = sender.send(EventMessage::BrowserCreated);\n\t\t\t}\n\t\t\tcontext\n\t\t}","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/desktop/ui/src/remote/host.rs#L35-L71","documentation":"Panic when the UI host's event_sender.send(EventMessage::Hello { ... }) fails. This ipc-channel send fails when the receiving end in the main Graphite process is gone: the main process exited or crashed after spawning the host, or it dropped the bootstrap receiver before the handshake completed. The preceding expect on the mutex ('cannot be poisoned before threads exist') indicates the send itself, not the lock, is the failure point.","triggerScenarios":"Main process dying between the host's connect() and the Hello send; main process crashing during startup so the bootstrap receiver is dropped; the host being started with a stale server address that happened to accept a connection but immediately closed it.","commonSituations":"Startup races where the parent is killed (OOM killer, watchdog, user Ctrl-C during launch); main-process panics in early initialization; mismatched protocol versions where the main process drops unknown senders.","solutions":["Check whether the main Graphite process (config.main_pid) is alive when the panic occurs and inspect its logs for a startup crash","If the main process was OOM-killed, free memory or raise limits and relaunch","Verify the host binary and main binary come from the same build (same IPC message types) to rule out protocol skew","Re-launch the app; capture both processes' logs if reproducible"],"exampleFix":"// before\n.expect(\"Failed to send Hello to the main process\");\n\n// after\nif let Err(e) = event_sender.lock().expect(\"The host message sender cannot be poisoned before threads exist\").send(EventMessage::Hello {\n\tpid: std::process::id(),\n\tcontrol_sender,\n\tacceleration,\n}) {\n\teprintln!(\"Failed to send Hello to the main process: {e} (main process exited during handshake)\");\n\tstd::process::exit(1);\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"let hello_result = event_sender\n\t.lock()\n\t.expect(\"The host message sender cannot be poisoned before threads exist\")\n\t.send(EventMessage::Hello { pid: std::process::id(), control_sender, acceleration });\nif hello_result.is_err() {\n\teprintln!(\"main process exited during Hello handshake; shutting down host\");\n\tstd::process::exit(1);\n}","preventionTips":["Treat the Hello handshake as fallible: the parent can die at any moment and the host must exit gracefully","Log the main process pid in host errors to correlate with parent crashes","Watch for OOM kills of the main process when hosts repeatedly fail the handshake at startup"],"tags":["rust","ipc","handshake","multi-process","cef"],"backgroundTag":"ipc-peer-disconnected","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}