Skip to content

esbuild fails resolving pg-cloudflare/dist/index.js (Hyperdrive + node-postgres) #1214

@mushan0x0

Description

@mushan0x0

Bug description

When using pg@8.20.0 (node-postgres) in combination with Hyperdrive + @opennextjs/cloudflare, opennextjs-cloudflare build fails inside esbuild with:

✘ [ERROR] Could not resolve "pg-cloudflare"

    .open-next/server-functions/default/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/stream.js:41:41:
      41 │     const { CloudflareSocket } = require('pg-cloudflare')
         ╵                                          ~~~~~~~~~~~~~~~

  The module "./dist/index.js" was not found on the file system:

    .open-next/server-functions/default/node_modules/.pnpm/pg@8.20.0/node_modules/pg-cloudflare/package.json:16:19:
      16 │         "require": "./dist/index.js"
         ╵                    ~~~~~~~~~~~~~~~~~

Root cause: pg/lib/stream.js gates the require('pg-cloudflare') behind a runtime isCloudflareRuntime() check (which reads navigator.userAgent === 'Cloudflare-Workers'). Next.js's @vercel/nft file tracer cannot statically resolve that dynamic require, so it only copies pg-cloudflare/package.json (and the non-workerd dist/empty.js that package.json#exports.default points to) into .open-next/server-functions/default/node_modules/pg-cloudflare/. The workerd condition's dist/index.js and esm/index.mjs are missing, so the OpenNext esbuild pass (which uses useWorkerdCondition: true by default) fails to resolve the module.

This effectively blocks the officially-recommended Cloudflare path ("use Hyperdrive with node-postgres").

Reproduction

  1. Install pg and use it from a Next 16 route handler:
import { Pool } from "pg";
const pool = new Pool({ connectionString: env.HYPERDRIVE.connectionString });
  1. pnpm exec opennextjs-cloudflare build
  2. Observe the above esbuild error.

Versions

  • next: 16.2.4
  • @opennextjs/cloudflare: 1.19.2
  • @opennextjs/aws: 3.10.2
  • pg: 8.20.0 (pg-cloudflare 1.3.0)

Expected behaviour

Either:

  • @opennextjs/cloudflare recognises pg/pg-cloudflare as a commonly-used dependency and ensures the workerd-conditioned files are copied into the server bundle, or
  • The docs call this out prominently and ship a ready-made outputFileTracingIncludes snippet for users.

Current workaround

Force Next to include pg-cloudflare/dist and pg-cloudflare/esm in the traced files:

// next.config.ts
const nextConfig: NextConfig = {
  outputFileTracingIncludes: {
    "**/*": [
      "./node_modules/pg-cloudflare/dist/**",
      "./node_modules/pg-cloudflare/esm/**",
    ],
  },
  // ...
};

After this, opennextjs-cloudflare build succeeds.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions