{"record":{"id":"5423b95b06638e01","repo":"gfx-rs/wgpu","slug":"wgpu-hal-invariant-was-violated-usage-error-tx","errorCode":null,"errorMessage":"wgpu-hal invariant was violated (usage error): {txt}","messagePattern":"wgpu-hal invariant was violated \\(usage error\\): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"wgpu-hal/src/lib.rs","lineNumber":511,"sourceCode":"    }\n}\n\n#[cfg(any(dx12, vulkan))]\nimpl From<AllocationSizes> for gpu_allocator::AllocationSizes {\n    fn from(value: AllocationSizes) -> gpu_allocator::AllocationSizes {\n        gpu_allocator::AllocationSizes::new(\n            value.min_device_memblock_size,\n            value.min_host_memblock_size,\n        )\n        .with_max_device_memblock_size(value.max_device_memblock_size)\n        .with_max_host_memblock_size(value.max_host_memblock_size)\n    }\n}\n\n#[allow(dead_code, reason = \"may be unused on some platforms\")]\n#[cold]\nfn hal_usage_error<T: fmt::Display>(txt: T) -> ! {\n    panic!(\"wgpu-hal invariant was violated (usage error): {txt}\")\n}\n\n#[allow(dead_code, reason = \"may be unused on some platforms\")]\n#[cold]\nfn hal_internal_error<T: fmt::Display>(txt: T) -> ! {\n    panic!(\"wgpu-hal ran into a preventable internal error: {txt}\")\n}\n\n#[derive(Clone, Debug, Eq, PartialEq, Error)]\npub enum ShaderError {\n    #[error(\"Compilation failed: {0:?}\")]\n    Compilation(String),\n    #[error(transparent)]\n    Device(#[from] DeviceError),\n}\n\n#[derive(Clone, Debug, Eq, PartialEq, Error)]\npub enum PipelineError {","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/gfx-rs/wgpu/blob/3e11ff59bf3f9795d285ecc045014089640d7248/wgpu-hal/src/lib.rs#L493-L529","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (hal embedder)\nunsafe { cmd_buf.set_bind_group(layout, group, &offsets) }; // offsets unchecked\n// after\nassert!(offsets.len() == layout.dynamic_offset_count as usize);\nassert!(offsets.iter().all(|o| *o < group_binding_size));\nunsafe { cmd_buf.set_bind_group(layout, group, &offsets) };","handlingStrategy":"try-catch","validationCode":"// embedders: pre-validate hal arguments\nassert_eq!(offsets.len(), layout.dynamic_count as usize);\nassert!(resource.is_alive());","typeGuard":"fn valid_dynamic_offsets(offsets: &[u32], layout: &HalBindGroupLayout) -> bool {\n    offsets.len() == layout.dynamic_count as usize\n}","tryCatchPattern":"std::panic::catch_unwind(|| unsafe {\n    hal_cmd.set_bind_group(layout, group, offsets)\n}).map_err(|p| format!(\"hal usage error: {p:?}\"))","preventionTips":["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."],"tags":["wgpu-hal","invariant-violation","panic","usage-error"],"backgroundTag":"hal-invariant-violated","analyzedSha":"3e11ff59bf3f9795d285ecc045014089640d7248","analyzedAt":"2026-09-03T01:43:21.459Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}