{"record":{"id":"82d6d77c6b66b064","repo":"PaddlePaddle/PaddleOCR","slug":"webgpu-is-unavailable-webgpustate-reason","errorCode":null,"errorMessage":"WebGPU is unavailable: ${webgpuState.reason}","messagePattern":"WebGPU is unavailable: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"paddleocr-js/packages/core/src/runtime/ort.ts","lineNumber":78,"sourceCode":"        reason: \"The browser did not return a WebGPU adapter.\"\n      };\n    }\n    return {\n      available: true,\n      reason: \"\"\n    };\n  } catch (err: unknown) {\n    return {\n      available: false,\n      reason: err instanceof Error ? err.message : \"Failed to request a WebGPU adapter.\"\n    };\n  }\n}\n\nexport function getProviderCandidates(backend: string, webgpuState: WebGpuState): string[][] {\n  if (backend === \"webgpu\") {\n    if (!webgpuState.available) {\n      throw new Error(`WebGPU is unavailable: ${webgpuState.reason}`);\n    }\n    return [[\"webgpu\"]];\n  }\n  if (backend === \"wasm\") {\n    return [[\"wasm\"]];\n  }\n  return webgpuState.available ? [[\"webgpu\"], [\"wasm\"]] : [[\"wasm\"]];\n}\n\nfunction applyOrtEnvironmentOptions(ort: OrtModule, ortOptions: OrtOptions): void {\n  const wasmOptions = ort.env.wasm;\n\n  if (ortOptions.wasmPaths !== undefined) {\n    wasmOptions.wasmPaths = ortOptions.wasmPaths;\n  }\n  if (ortOptions.numThreads !== undefined) {\n    wasmOptions.numThreads = ortOptions.numThreads;\n  }","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr-js/packages/core/src/runtime/ort.ts#L60-L96","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Switch to backend: \"auto\" so the runtime falls back to wasm when WebGPU is unavailable","Verify WebGPU first (navigator.gpu && await navigator.gpu.requestAdapter()) and only then select \"webgpu\"","Fix the environment: enable hardware acceleration, install Vulkan drivers on Linux/WSL, or use a WebGPU-capable browser (Chrome 113+)","In headless Chrome, launch with --enable-unsafe-webgpu / --use-gl=angle and a GPU-enabled flag set"],"exampleFix":"// before\nconst ocr = await PaddleOCR.create({ backend: \"webgpu\" }); // throws on machines without WebGPU\n\n// after\nconst adapter = navigator.gpu ? await navigator.gpu.requestAdapter() : null;\nconst ocr = await PaddleOCR.create({ backend: adapter ? \"webgpu\" : \"wasm\" });","handlingStrategy":"validation","validationCode":"async function probeWebGpu(): Promise<boolean> {\n  try {\n    if (!(\"gpu\" in navigator)) return false;\n    return (await navigator.gpu.requestAdapter()) !== null;\n  } catch { return false; }\n}","typeGuard":"function hasNavigatorGpu(nav: Navigator): nav is Navigator & { gpu: GPU } {\n  return \"gpu\" in nav && typeof (nav as { gpu?: unknown }).gpu === \"object\";\n}","tryCatchPattern":"try {\n  return await create({ backend: \"webgpu\" });\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith(\"WebGPU is unavailable\")) {\n    return await create({ backend: \"wasm\" }); // graceful degradation\n  }\n  throw e;\n}","preventionTips":["Prefer backend: \"auto\" unless WebGPU is strictly required","Probe adapter availability before pinning \"webgpu\"","Test on real GPU hardware; headless CI needs explicit GPU flags"],"tags":["webgpu","ort","runtime","feature-detection","gpu"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}