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
- Use the try_wgpu_executor node to obtain Option<&WgpuExecutor> and route to CPU fallback nodes when it is None
- Fix GPU initialization: enable WebGPU in the browser, install/update GPU drivers, or run against a software adapter (lavapipe/LLVMpipe)
- Inspect startup logs from adapter/device creation to see why no GPU executor was attached to ApplicationIo
- 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
- Feature-detect the GPU executor at application startup (try_wgpu_executor returns Option) and remember the result
- In browsers, verify WebGPU availability (navigator.gpu) before enabling GPU-dependent graphs
- Maintain CPU-node equivalents for GPU-only operations so absence degrades instead of panicking
- On desktop, fall back to a software adapter (lavapipe/LLVMpipe) when hardware adapter requests fail
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
- ApplicationIo not available
- GPU executor not available
- GPU executor not available
- GPU executor should be available when we receive a texture
- ApplicationIo must be available when using resources
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/210878555b6e2330.
Report an issue: GitHub.