PaddlePaddle/PaddleOCR · error · Error

WebGPU is unavailable: ${webgpuState.reason}

Error message

WebGPU is unavailable: ${webgpuState.reason}

What it means

Thrown by getProviderCandidates() when the user explicitly requests backend "webgpu" but the earlier WebGPU probe failed (navigator.gpu missing, adapter request rejected, or adapter deemed unusable). The error message embeds the probe's reason. Explicit backend selection is strict: with "auto" the library would silently fall back to wasm, but "webgpu" refuses to run on a machine without working WebGPU.

Source

Thrown at paddleocr-js/packages/core/src/runtime/ort.ts:78

        reason: "The browser did not return a WebGPU adapter."
      };
    }
    return {
      available: true,
      reason: ""
    };
  } catch (err: unknown) {
    return {
      available: false,
      reason: err instanceof Error ? err.message : "Failed to request a WebGPU adapter."
    };
  }
}

export function getProviderCandidates(backend: string, webgpuState: WebGpuState): string[][] {
  if (backend === "webgpu") {
    if (!webgpuState.available) {
      throw new Error(`WebGPU is unavailable: ${webgpuState.reason}`);
    }
    return [["webgpu"]];
  }
  if (backend === "wasm") {
    return [["wasm"]];
  }
  return webgpuState.available ? [["webgpu"], ["wasm"]] : [["wasm"]];
}

function applyOrtEnvironmentOptions(ort: OrtModule, ortOptions: OrtOptions): void {
  const wasmOptions = ort.env.wasm;

  if (ortOptions.wasmPaths !== undefined) {
    wasmOptions.wasmPaths = ortOptions.wasmPaths;
  }
  if (ortOptions.numThreads !== undefined) {
    wasmOptions.numThreads = ortOptions.numThreads;
  }

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Switch to backend: "auto" so the runtime falls back to wasm when WebGPU is unavailable
  2. Verify WebGPU first (navigator.gpu && await navigator.gpu.requestAdapter()) and only then select "webgpu"
  3. Fix the environment: enable hardware acceleration, install Vulkan drivers on Linux/WSL, or use a WebGPU-capable browser (Chrome 113+)
  4. In headless Chrome, launch with --enable-unsafe-webgpu / --use-gl=angle and a GPU-enabled flag set

Example fix

// before
const ocr = await PaddleOCR.create({ backend: "webgpu" }); // throws on machines without WebGPU

// after
const adapter = navigator.gpu ? await navigator.gpu.requestAdapter() : null;
const ocr = await PaddleOCR.create({ backend: adapter ? "webgpu" : "wasm" });
Defensive patterns

Strategy: validation

Validate before calling

async function probeWebGpu(): Promise<boolean> {
  try {
    if (!("gpu" in navigator)) return false;
    return (await navigator.gpu.requestAdapter()) !== null;
  } catch { return false; }
}

Type guard

function hasNavigatorGpu(nav: Navigator): nav is Navigator & { gpu: GPU } {
  return "gpu" in nav && typeof (nav as { gpu?: unknown }).gpu === "object";
}

Try / catch

try {
  return await create({ backend: "webgpu" });
} catch (e) {
  if (e instanceof Error && e.message.startsWith("WebGPU is unavailable")) {
    return await create({ backend: "wasm" }); // graceful degradation
  }
  throw e;
}

Prevention

When it happens

Trigger: create({ backend: "webgpu" }) on Chrome without --enable-unsafe-webgpu on older versions, Linux without proper GPU drivers, remote desktop/VM with software rendering, browsers where navigator.gpu is undefined (Firefox older builds, Safari < 18 / TP without the flag), or adapter.requestAdapter() returning null.

Common situations: Dev machines on Linux/WSL with missing Vulkan drivers; corporate VMs; assuming WebGPU is universally available after reading Chrome-113 announcements; CI headless browsers without GPU.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/82d6d77c6b66b064. Report an issue: GitHub.