GraphiteEditor/Graphite · error

GPU executor not available

Error message

GPU executor not available

What it means

The second assertion in the wgpu_executor node: application_io exists but its gpu_executor() returned None, so the platform IO backend has no GPU executor attached, and .expect("GPU executor not available") panics. This happens when GPU initialization never succeeded (wgpu adapter/device request failed, e.g. no suitable adapter or WebGPU unavailable) or on platforms whose ApplicationIo deliberately ships without GPU support. try_wgpu_executor handles this case without panicking.

Source

Thrown at node-graph/nodes/gstd/src/platform_application_io.rs:306

	editor_api: Item<&'a PlatformEditorApi>,
	/// The content hash identifying which stored resource to load.
	hash: Item<ResourceHash>,
) -> Item<Resource> {
	let hash = hash.into_element();
	let application_io = editor_api.into_element().application_io.as_ref().expect("ApplicationIo must be available when using resources");
	let resource = application_io.load_resource(hash).await.unwrap_or_else(|| panic!("Resource {hash} not found"));
	Item::new_from_element(resource)
}

#[node_macro::node(category(""), inject_scope)]
pub async fn wgpu_executor<'a: 'n>(_: impl Ctx, #[scope(editor_api::IDENTIFIER)] editor_api: Item<&'a PlatformEditorApi>) -> Item<&'a ::wgpu_executor::WgpuExecutor> {
	let executor = editor_api
		.into_element()
		.application_io
		.as_ref()
		.expect("ApplicationIo not available")
		.gpu_executor()
		.expect("GPU executor not available");
	Item::new_from_element(executor)
}

#[node_macro::node(category(""), inject_scope)]
pub async fn try_wgpu_executor<'a: 'n>(_: impl Ctx, #[scope(editor_api::IDENTIFIER)] editor_api: Item<&'a PlatformEditorApi>) -> Item<Option<&'a ::wgpu_executor::WgpuExecutor>> {
	let executor = editor_api.into_element().application_io.as_ref().and_then(|application_io| application_io.gpu_executor());
	Item::new_from_element(executor)
}

/// Uploads image data from CPU memory into a GPU texture so that GPU-based nodes can process it.
#[node_macro::node(category("Debug"), memoize)]
pub async fn upload_texture<'a: 'n>(_: impl Ctx, content: Item<Raster<CPU>>, #[scope(wgpu_executor::IDENTIFIER)] executor: Item<&'a ::wgpu_executor::WgpuExecutor>) -> Item<Raster<GPU>> {
	let executor = executor.into_element();
	let (raster, attributes) = content.into_parts();

	Item::from_parts(raster.convert(Footprint::DEFAULT, executor).await, attributes)
}

View on GitHub (pinned to c507b35645)

Solutions

  1. Use the try_wgpu_executor node to obtain Option<&WgpuExecutor> and route to CPU fallback nodes when it is None
  2. Fix GPU initialization: enable WebGPU in the browser, install/update GPU drivers, or run against a software adapter (lavapipe/LLVMpipe)
  3. Inspect startup logs from adapter/device creation to see why no GPU executor was attached to ApplicationIo
  4. Replace .expect with error propagation so the graph reports a missing GPU backend as a node error

Example fix

// before
let executor = editor_api.into_element().application_io.as_ref().expect("ApplicationIo not available").gpu_executor().expect("GPU executor not available");

// after: use the non-panicking sibling node and degrade explicitly
let executor: Option<&WgpuExecutor> = try_wgpu_executor(...).await.into_element();
match executor {
    Some(executor) => gpu_path(executor).await,
    None => cpu_fallback_path().await,
}
Defensive patterns

Strategy: fallback

Validate before calling

let has_gpu = editor_api
    .application_io
    .as_ref()
    .and_then(|io| io.gpu_executor())
    .is_some();
if !has_gpu {
    // route the graph to CPU nodes / show a 'GPU unavailable' notice before evaluation
}

Type guard

fn has_gpu_executor(api: &PlatformEditorApi) -> bool {
    api.application_io.as_ref().and_then(|io| io.gpu_executor()).is_some()
}

Try / catch

let outcome = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| evaluate_gpu_graph(doc)));
if outcome.is_err() {
    // GPU backend missing: fall back to CPU node graph or report to the user
}

Prevention

When it happens

Trigger: Requesting the GPU executor scope dependency on a machine/browser where the wgpu adapter request failed (no Vulkan/Metal/DX12/WebGPU), where device creation was blocked by driver blacklist or policy, or where the platform's ApplicationIo variant does not construct a GPU executor at all.

Common situations: Browsers with WebGPU disabled or unsupported; VMs and remote-desktop sessions without GPU passthrough; CI runners without GPUs; systems whose drivers fail wgpu device creation; stale GPU drivers.

Related errors


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