Skip to content

[BUG] WASM solver crashes on WebKit (iOS Safari / macOS Safari) — null #c._ensureSize #203

@byrnajkhan

Description

@byrnajkhan

Description

The Cap.js widget's WASM proof-of-work solver crashes on all WebKit-based browsers (Mobile Safari, Chrome Mobile iOS, DuckDuckGo iOS, Edge iOS, Firefox iOS, Safari macOS). The error is an unhandled promise rejection from the minified widget code.

Error

TypeError: null is not an object (evaluating 'this.#c._ensureSize')

Source: @cap.js/widget@latest/cap.min.js:1:8997 (minified function #f)
Mechanism: onunhandledrejection — the promise rejection is unhandled, so the widget silently breaks.

Impact

  • 65 occurrences across 54 unique users over 16 days (March 2–18, 2026)
  • Affects /register and /rma pages where the Cap widget is used
  • The widget becomes non-functional — users cannot complete the captcha, blocking form submission

Environment

Browser Occurrences
Mobile Safari 30
Safari (macOS) 9
Chrome Mobile iOS 6
DuckDuckGo Mobile/Desktop 3
Edge Mobile (iOS) 2
Firefox iOS 1
Other iOS WebViews 2

100% WebKit engine. Zero occurrences on Chromium (Android/Windows) or Gecko (Firefox desktop).

iOS versions observed: 18.x, 26.x
Safari versions observed: 18.6, 26.2, 26.3

Analysis

The private class field #c appears to be the WASM module instance. _ensureSize is characteristic of wasm-bindgen generated memory management code. The crash indicates that WASM initialization failed silently — the module instance is null when the solver later attempts to use it.

Possible contributing factors:

Expected Behavior

If WASM initialization fails, the widget should:

  1. Catch the initialization failure
  2. Fall back to the pure JavaScript SHA-256 solver
  3. Or at minimum, surface a meaningful error via the error event so the host page can handle it

Current Behavior

The WASM init failure goes undetected. When the solver later tries to use the null WASM instance, it throws an unhandled rejection that the host page cannot catch through normal Cap widget event listeners.

Reproduction

This appears to be intermittent and tied to WebKit's WASM runtime behavior. We see it consistently across multiple iOS versions and all WebKit-based browsers, but not on every page load. It may be related to memory pressure or timing of Web Worker initialization.

Widget Version

Loaded via CDN: https://cdn.jsdelivr.net/npm/@cap.js/widget@latest/cap.min.js

Suggested Fix

Add a null-check on the WASM module instance before calling _ensureSize, and implement automatic fallback to the JS solver when WASM initialization fails.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions