moeru-ai/airi · warning
[BG Removal Worker] WebGPU not available, falling back to WA
Error message
[BG Removal Worker] WebGPU not available, falling back to WASM
What it means
The background-removal worker mirrors the Whisper worker's device probe: when a request asks for device 'webgpu' (the default when request.device is unset) but detectWebGPUInWorker() finds no navigator.gpu, it logs this, downgrades to device 'wasm', and sets env.backends.onnx.wasm.proxy = false so the ONNX model runs directly on the worker thread. Background removal still works, just on CPU/WASM at lower throughput.
Source
Thrown at packages/stage-ui/src/workers/background-removal/worker.ts:145
clearCancelled(requestId)
return
}
const ready: ModelReadyResponse = {
type: 'model-ready',
requestId,
modelId: MODEL_NAMES.BG_REMOVAL,
device: resolvedDevice,
}
globalThis.postMessage(ready)
return
}
// Auto-detect: if WebGPU was requested but unavailable, fall back to WASM
let device = request.device ?? 'webgpu'
if (device === 'webgpu') {
const hasWebGPU = await detectWebGPUInWorker()
if (!hasWebGPU) {
console.warn('[BG Removal Worker] WebGPU not available, falling back to WASM')
device = 'wasm'
}
}
resolvedDevice = device as 'webgpu' | 'wasm' | 'cpu'
env.backends.onnx.wasm!.proxy = false
model = await AutoModel.from_pretrained(MODEL_ID, {
device,
progress_callback: (progress: any) => {
sendProgress(requestId, progress?.progress ?? -1, progress?.status)
},
})
processor = await AutoProcessor.from_pretrained(MODEL_ID, {})
if (isCancelled(requestId)) {
clearCancelled(requestId)View on GitHub (pinned to 677329427f)
Solutions
- Verify WebGPU availability in that browser (chrome://gpu or 'gpu' in navigator)
- Update the browser / drivers if the hardware supports WebGPU
- Pass device: 'wasm' in the request to skip the probe and the warning when GPU absence is expected
- Use a smaller bg-removal model or lower-resolution input to offset WASM latency
Example fix
// before
worker.postMessage({ type: 'run', /* device defaults to 'webgpu' */ })
// after
const device = 'gpu' in navigator ? 'webgpu' : 'wasm'
worker.postMessage({ type: 'run', device }) Defensive patterns
Strategy: fallback
Validate before calling
const device: 'webgpu' | 'wasm' = 'gpu' in navigator ? 'webgpu' : 'wasm'
worker.postMessage({ type: 'run', requestId, device }) Try / catch
try {
await runRemoval({ device: 'webgpu' })
}
catch {
await runRemoval({ device: 'wasm' })
} Prevention
- Pass an explicit device based on a main-thread navigator.gpu probe
- Reduce input resolution for WASM-only environments
- Remember env.backends.onnx.wasm.proxy is forced false in this worker - keep heavy work off the main thread
When it happens
Trigger: Any default request (or explicit device 'webgpu') in a browser/context without WebGPU: Firefox, older Chromium/Safari, driver blocklists, headless CI, VMs with software renderers, or worker scopes where navigator.gpu is not exposed.
Common situations: Users on WebGPU-less browsers experience slower background removal; automated screenshot pipelines; machines where the GPU driver is blocklisted.
Related errors
- [Whisper Worker] WebGPU not available, falling back to WASM
- [Whisper Worker] fp16 encoder failed, falling back to fp32:
- [Kokoro Worker] Failed with dtype=${attempt.dtype} device=${
- Failed to ensure MediaPipe WASM assets: ${wasmOutputDir} is
- Invalid VRAM override: ${bytes} (expected null or non-negati
AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18).
Data as JSON: /api/errors/7a16c92983caf2cd.
Report an issue: GitHub.