gfx-rs/wgpu · error
wgpu-hal invariant was violated (usage error): {txt}
Error message
wgpu-hal invariant was violated (usage error): {txt} What it means
hal_usage_error is wgpu-hal's marker panic for a violated HAL invariant: wgpu-core passed arguments to the backend that the WebGPU validation layer should have rejected (or that are impossible per the API contract). It signals a usage error reaching the backend, i.e. a bug in wgpu-core's validation or a broken unsafe caller — not a runtime environment problem. The message includes `txt` describing which invariant was broken.
Source
Thrown at wgpu-hal/src/lib.rs:511
}
}
#[cfg(any(dx12, vulkan))]
impl From<AllocationSizes> for gpu_allocator::AllocationSizes {
fn from(value: AllocationSizes) -> gpu_allocator::AllocationSizes {
gpu_allocator::AllocationSizes::new(
value.min_device_memblock_size,
value.min_host_memblock_size,
)
.with_max_device_memblock_size(value.max_device_memblock_size)
.with_max_host_memblock_size(value.max_host_memblock_size)
}
}
#[allow(dead_code, reason = "may be unused on some platforms")]
#[cold]
fn hal_usage_error<T: fmt::Display>(txt: T) -> ! {
panic!("wgpu-hal invariant was violated (usage error): {txt}")
}
#[allow(dead_code, reason = "may be unused on some platforms")]
#[cold]
fn hal_internal_error<T: fmt::Display>(txt: T) -> ! {
panic!("wgpu-hal ran into a preventable internal error: {txt}")
}
#[derive(Clone, Debug, Eq, PartialEq, Error)]
pub enum ShaderError {
#[error("Compilation failed: {0:?}")]
Compilation(String),
#[error(transparent)]
Device(#[from] DeviceError),
}
#[derive(Clone, Debug, Eq, PartialEq, Error)]
pub enum PipelineError {View on GitHub (pinned to 3e11ff59bf)
Solutions
- If you use the wgpu Rust API: this is a wgpu bug — reduce to a minimal reproducer and file an issue at github.com/gfx-rs/wgpu with the panic text.
- If you embed wgpu-hal directly: validate arguments against the backend contract before calling hal functions; the panic is by-design protection.
- Check for resource destruction races: keep resources alive until submission fences complete (hold Arc/refs or use on_submitted_work_done).
- Pin to a wgpu version known-good for your workload or apply the fix from a newer release if the issue is already fixed upstream.
Example fix
// before (hal embedder)
unsafe { cmd_buf.set_bind_group(layout, group, &offsets) }; // offsets unchecked
// after
assert!(offsets.len() == layout.dynamic_offset_count as usize);
assert!(offsets.iter().all(|o| *o < group_binding_size));
unsafe { cmd_buf.set_bind_group(layout, group, &offsets) }; Defensive patterns
Strategy: try-catch
Validate before calling
// embedders: pre-validate hal arguments assert_eq!(offsets.len(), layout.dynamic_count as usize); assert!(resource.is_alive());
Type guard
fn valid_dynamic_offsets(offsets: &[u32], layout: &HalBindGroupLayout) -> bool {
offsets.len() == layout.dynamic_count as usize
} Try / catch
std::panic::catch_unwind(|| unsafe {
hal_cmd.set_bind_group(layout, group, offsets)
}).map_err(|p| format!("hal usage error: {p:?}")) Prevention
- If using the wgpu Rust API and this fires, file a minimal reproducer upstream — it is a bug.
- For hal embedders, re-validate every argument against backend contracts.
- Keep resources alive until GPU submissions complete to avoid use-after-destroy.
- Pin wgpu versions and test upgrades for validation regressions.
When it happens
Trigger: Calling wgpu-hal APIs directly with invalid arguments (custom integrations like Deno/Firefox embedders); hitting a wgpu-core validation gap where an invalid resource/state combination is forwarded to the backend, e.g. bad bind group slot, out-of-range dynamic offsets, mismatched buffer usage at map time.
Common situations: Embedders bypassing wgpu-core; newly added wgpu-core features with incomplete validation; race conditions where a resource was destroyed while still referenced by an in-flight submission; reporting bugs upstream when this fires during ordinary wgpu API use.
Related errors
- Feature `MESH_SHADING` not enabled
- {:?} is not enabled for this backend
- wgpu-hal ran into a preventable internal error: {txt}
- wgpu error: {err}
- Mismatched pop_error_scope call: no error scope for this thr
AI-assisted analysis of gfx-rs/wgpu@3e11ff59bf (2026-09-03).
Data as JSON: /api/errors/5423b95b06638e01.
Report an issue: GitHub.