gfx-rs/wgpu · error

Unexpected error: constructor={constructor} value={value}

Error message

Unexpected error: constructor={constructor} value={value}

What it means

In the WebGPU (browser) backend, error_from_js converts a JavaScript exception into a Rust error; if the JS value is not one of the recognized WebGPU error DOMException types, it panics with the constructor name and stringified value. It is reached from future_pop_error_scope and on_uncaptured_error when the browser surfaces an unexpected exception.

Source

Thrown at wgpu/src/backend/webgpu.rs:95

        crate::Error::Validation {
            source,
            description: js_error.message(),
        }
    } else if let Some(js_error) = js_error.dyn_ref::<webgpu_sys::GpuInternalError>() {
        crate::Error::Internal {
            source,
            description: js_error.message(),
        }
    } else if js_error.has_type::<webgpu_sys::GpuOutOfMemoryError>() {
        crate::Error::OutOfMemory { source }
    } else {
        let constructor = js_error
            .constructor()
            .name()
            .as_string()
            .unwrap_or_default();
        let value = js_error.to_string().as_string().unwrap_or_default();
        panic!("Unexpected error: constructor={constructor} value={value}");
    }
}

/// A callback invoked when wgpu releases its reference to an externally
/// owned WebGPU resource (e.g. a `GpuTexture` passed to
/// [`crate::Device::create_texture_from_webgpu_handle`]).
///
/// This is the WebGPU counterpart of [`wgpu_hal::DropCallback`].
pub type DropCallback = Box<dyn FnOnce() + 'static>;

pub(crate) struct DropGuard {
    callback: Option<DropCallback>,
}

impl DropGuard {
    fn new(callback: Option<DropCallback>) -> Self {
        Self { callback }
    }

View on GitHub (pinned to 3e11ff59bf)

Solutions

  1. Inspect the printed constructor= and value= to identify the underlying JS exception and fix the call that caused it.
  2. Capture errors with device.push_error_scope/pop_error_scope and on_uncaptured_error handlers so failures are handled before reaching this path.
  3. Update wgpu and the browser to compatible versions if the exception comes from a browser-specific quirk.

Example fix

// before
// no handler: JS exception becomes a panic
// after
device.on_uncaptured_error(Box::new(|err| {
    log::error!("wgpu error: {err}");
}));
Defensive patterns

Strategy: try-catch

Validate before calling

device.push_error_scope(wgpu::ErrorFilter::Validation);
// ... GPU work ...
let err = device.pop_error_scope().await;

Try / catch

// in on_uncaptured_error / pop_error_scope, log and recover instead of letting the JS exception propagate:
device.on_uncaptured_error(Box::new(|err| log::error!("wgpu: {err}")));

Prevention

When it happens

Trigger: An uncaptured JS error or popped error scope containing a non-WebGPU exception (e.g. TypeError, RangeError, or an arbitrary thrown value) instead of a GPUValidationError/GPUOutOfMemoryError/GPUInternalError.

Common situations: Browser bugs or vendor extensions surfacing non-standard exceptions; passing invalid JS objects into WebGPU; device-lost / context-loss paths in some browsers; mismatched web-sys versions exposing unknown error constructors.

Related errors


AI-assisted analysis of gfx-rs/wgpu@3e11ff59bf (2026-09-03). Data as JSON: /api/errors/fa73cc138f65e7bd. Report an issue: GitHub.