GraphiteEditor/Graphite · critical

Failed to send editor preferences

Error message

Failed to send editor preferences

What it means

update_editor_preferences forwards an EditorPreferencesUpdate over the same mpsc request channel to the NodeRuntime thread and expects the send to succeed. The expect fires when the runtime thread no longer exists (it panicked or was torn down), so any preferences change (e.g., theme/performance settings applied mid-session) crashes the main thread. As with the execution-request variant, the channel failure is downstream evidence that the runtime worker died earlier; the send error string is produced by NodeRuntimeIO::send mapping SendError to String.

Source

Thrown at editor/src/node_graph_executor.rs:133

			gradient_migration_attempted: HashSet::new(),
		};
		(node_runtime, node_executor)
	}

	/// Execute the network by flattening it and creating a borrow stack.
	fn queue_execution(&mut self, render_config: RenderConfig) -> u64 {
		let execution_id = self.current_execution_id;
		self.current_execution_id += 1;
		let request = ExecutionRequest { execution_id, render_config };
		self.runtime_io.send(GraphRuntimeRequest::ExecutionRequest(request)).expect("Failed to send generation request");

		execution_id
	}

	pub fn update_editor_preferences(&self, editor_preferences: EditorPreferences) {
		self.runtime_io
			.send(GraphRuntimeRequest::EditorPreferencesUpdate(editor_preferences))
			.expect("Failed to send editor preferences");
	}

	/// Updates the network to monitor all inputs. Useful for the testing.
	#[cfg(test)]
	pub(crate) fn update_node_graph_instrumented(&mut self, document: &mut DocumentMessageHandler) -> Result<Instrumented, String> {
		// We should always invalidate the cache.
		self.node_graph_hash = crate::application::generate_uuid();
		let mut network = document.network_interface.document_network().clone();
		let instrumented = Instrumented::new(&mut network);

		let resources = document.resources.registry.clone();

		self.runtime_io
			.send(GraphRuntimeRequest::GraphUpdate(GraphUpdate {
				network,
				resources,
				node_to_inspect: Vec::new(),
			}))

View on GitHub (pinned to c507b35645)

Solutions

  1. Treat a send failure as 'runtime unavailable': log and skip the update instead of expecting, since preferences can be re-applied when a runtime is recreated.
  2. Diagnose the runtime death: search logs above this panic for the original NodeRuntime panic backtrace and fix that node/thread issue.
  3. Add a shutdown guard so preference pushes are suppressed once teardown begins.
  4. In tests, drive preferences updates through an executor with a live channel pair (with_channels) rather than a dropped receiver.

Example fix

// before
self.runtime_io
	.send(GraphRuntimeRequest::EditorPreferencesUpdate(editor_preferences))
	.expect("Failed to send editor preferences");

// after
if self.runtime_io.send(GraphRuntimeRequest::EditorPreferencesUpdate(editor_preferences)).is_err() {
	log::warn!("node runtime unavailable; editor preferences not pushed");
}
Defensive patterns

Strategy: fallback

Validate before calling

if self.runtime_io.send(GraphRuntimeRequest::EditorPreferencesUpdate(editor_preferences)).is_ok() {
	// preferences will be applied by the runtime
} else {
	// runtime gone: keep local state; re-push when a runtime is recreated
}

Try / catch

if let Err(err) = self.runtime_io.send(GraphRuntimeRequest::EditorPreferencesUpdate(editor_preferences)) {
	log::warn!("editor preferences not delivered: {err}");
}

Prevention

When it happens

Trigger: Changing editor preferences while the NodeRuntime worker thread has already terminated: runtime_io.send(GraphRuntimeRequest::EditorPreferencesUpdate(...)).expect("Failed to send editor preferences") receives a disconnected-channel error and panics.

Common situations: A prior runtime-thread panic in node execution followed by any preferences update; shutdown ordering where the runtime is dropped before the final preference sync; tests that construct executors without a live runtime and then call update_editor_preferences.

Related errors


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