Skip to content

@elysiajs/swagger incompatible with Cloudflare Workers — async I/O in global scope #332

@jasongitmail

Description

@jasongitmail

What version of @elysiajs/swagger is running?

1.3.1

What version of Elysia is running?

1.3.3 (with elysia/adapter/cloudflare-worker)

What platform is your computer?

Darwin 25.1.0 arm64 (wrangler 4.7.0)

What steps can reproduce the bug?

import { swagger } from "@elysiajs/swagger";
import { Elysia } from "elysia";
import { CloudflareAdapter } from "elysia/adapter/cloudflare-worker";

export const app = new Elysia({ adapter: CloudflareAdapter })
  .use(swagger({ path: "/openapi" }))
  .get("/", () => "Hello")
  .compile();

export default { fetch: app.fetch };

Run with wrangler dev.

What is the expected behavior?

The swagger UI should be served at /openapi.

What do you see instead?

✘ [ERROR] service core:user:...: Uncaught Error: Disallowed operation called within global scope.
Asynchronous I/O (ex: fetch() or connect()), setting a timeout, and generating
random values are not allowed within global scope.

    at null.<anonymous> (index.js:29178:16) in swagger

The plugin performs a fetch() at initialization time (presumably to load Swagger/Scalar UI assets). Cloudflare Workers forbids async I/O in the module's global scope — it can only happen inside request handlers.

Moving the plugin initialization into a request handler avoids the global scope error but then hits a second issue: Elysia's composeErrorHandler / composeGeneralHandler uses new Function(), which workerd also blocks (EvalError: Code generation from strings disallowed for this context).

Workaround

Serve a static Scalar UI HTML page and a hand-written OpenAPI JSON spec as plain Elysia routes, bypassing the plugin entirely.

Additional information

  • aot: false does not help — it avoids the new Function() error but the global-scope async I/O error from the swagger plugin still occurs first.
  • The Cloudflare adapter + .compile() works fine for all other Elysia features.
  • This effectively means @elysiajs/swagger cannot be used on Cloudflare Workers at all.

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