Skip to content

[BUG] protobufjs codegen uses new Function() at runtime, crashes in Workers (firebase/firestore) #1301

Description

@SybyAbraham

Description

When using firebase/firestore in a Next.js app deployed with @opennextjs/cloudflare, the Worker crashes at runtime with:

EvalError: Code generation from strings disallowed for this context
    at Function (<anonymous>)
    at f (handler.mjs:183:36652)
    at s.get (handler.mjs:186:35283)
    at j.resolve (handler.mjs:186:51343)
    at s.resolveAll (handler.mjs:186:37884)
    at l.fromJSON (handler.mjs:186:41702)

The failing code comes from @protobufjs/codegen, which uses dynamic function generation:

Function.apply(null, scopeParams).apply(null, scopeValues)
Function(source)()

In this build, the path appears to be:

firebase/firestore
  -> @firebase/firestore node export
  -> @grpc/proto-loader
  -> protobufjs/ext/descriptor
  -> Root.fromJSON(require("../../google/protobuf/descriptor.json"))
  -> @protobufjs/codegen

protobufjs/ext/descriptor calls Root.fromJSON(...) at module initialization, so the Worker can crash as soon as the generated chunk is loaded.

Why this seems to surface with Next.js 16

This did not happen for the same app on Next.js 15. After upgrading to Next.js 16, the generated Worker chunk loads the CommonJS path eagerly enough that the protobufjs/ext/descriptor initialization runs and hits new Function().

I do not know whether this is specifically caused by Turbopack evaluation order, different tree-shaking, or a changed server bundle path, but the crash appears after moving to Next.js 16.

Compatibility date note

This is happening with:

"compatibility_date": "2026-07-01",
"compatibility_flags": ["nodejs_compat"]

Cloudflare's allow_eval_during_startup behavior should already be enabled for this compatibility date, so either this code is not being treated as startup eval in the generated Worker path, or the failing call happens outside the allowed startup window.

Current workaround

I am currently applying a post-build patch to .open-next/server-functions/default/handler.mjs:

content = content.replace(
  /Function\.apply\(null,(\w+)\)\.apply\(null,(\w+)\)/g,
  "(function(){try{return Function.apply(null,$1).apply(null,$2)}catch(e){return function(){}}})()"
);

content = content.replace(
  /return Function\((\w+)\)\(\)/g,
  "return(function(){try{return Function($1)()}catch(e){return function(){}}})()"
);

This prevents the Worker from crashing during startup, but it is not a proper semantic fix. If protobufjs later depends on one of those generated constructors/encoders/decoders, this may return a no-op function instead of preserving protobufjs behavior.

Suggested direction

It would be useful for @opennextjs/cloudflare to either:

  • avoid bundling the Node/gRPC Firestore path when targeting Workers, if the Firebase browser/client path is appropriate; or
  • handle this protobufjs codegen pattern in a way that preserves behavior; or
  • document the expected workaround if this dependency path is not supportable in Workers.

@opennextjs/cloudflare already patches some Worker-incompatible generated code such as eval("require"), so this may fit into the same general compatibility area, but the current no-op workaround is probably not suitable as an upstream patch.

Environment

  • @opennextjs/cloudflare: 1.20.1
  • next: 16.2.10
  • firebase: 11.x (@firebase/firestore pulls in protobufjs)
  • wrangler: 4.106.0
  • Compatibility date: 2026-07-01
  • Compatibility flags: nodejs_compat

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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