Skip to content

@cloudflare/opaque-ts crashes under Cloudflare Workers / vitest-pool-workers during module load via @cloudflare/voprf-ts sjcl interop #31

@astanciu

Description

@astanciu

Summary

@cloudflare/opaque-ts fails to load in the Cloudflare Workers Vitest runtime.

If a Worker entrypoint imports code that eventually imports @cloudflare/opaque-ts, tests fail before any tests execute.

The failure happens during module evaluation, not when actually calling OPAQUE APIs.

Environment

  • @cloudflare/opaque-ts: 0.7.5
  • @cloudflare/vitest-pool-workers: 0.14.7
  • vitest: 4.1.4
  • wrangler: 4.83.0
  • Node: v24.1.0
  • OS: macOS

Error

TypeError: Cannot set property default of [object Module] which has only a getter
❯ .../@cloudflare/voprf-ts/lib/src/sjcl/index.js:3141:20
3139| };
3140| if (typeof module !== 'undefined' && module.exports) {
3141|     module.exports = sjcl;

This appears to come from the @cloudflare/opaque-ts -> @cloudflare/voprf-ts -> sjcl path.

Expected behavior

A Worker module graph that imports @cloudflare/opaque-ts should be loadable in the Cloudflare Workers runtime / test runtime.

Actual behavior

The runtime crashes during module load and no tests run.

Repro shape

I have a Worker entrypoint that imports an auth service graph. That graph includes an OpaqueService which imports @cloudflare/opaque-ts.

  • If my Vitest Worker config points main at the real Worker entrypoint, the suites fail immediately with the error above.
  • If I instead point main at a minimal test-only Worker that avoids importing the auth graph / @cloudflare/opaque-ts, the same tests pass.

So the issue is specifically triggered by loading @cloudflare/opaque-ts in the Workers runtime.

Additional notes

I also tried forcing the dependency chain through Vitest/Vite transforms:

  • server.deps.inline
  • ssr.noExternal

for:

  • @cloudflare/opaque-ts
  • @cloudflare/voprf-ts
  • sjcl

That did not change the failure.

It looks like the problem is the sjcl interop inside @cloudflare/voprf-ts, which @cloudflare/opaque-ts pulls in.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions