Skip to content

@google-cloud/secret-manager generated protos expose protobufjs/minimal to bundlers under pnpm #8227

@ManuelCortes23

Description

@ManuelCortes23

Package

@google-cloud/secret-manager

Version

Observed with:

  • @google-cloud/secret-manager@6.1.2
  • google-gax@5.0.6
  • pnpm@10.33.2
  • next@15.5.15 / webpack production build
  • Vercel build environment

What happened?

A Next.js/Vercel production build failed while bundling an API route that imports Secret Manager:

Failed to compile.
../../node_modules/.pnpm/@google-cloud+secret-manager@6.1.2/node_modules/@google-cloud/secret-manager/build/protos/protos.js
Module not found: Can't resolve 'protobufjs/minimal'

Import trace for requested module:
../../node_modules/.pnpm/@google-cloud+secret-manager@6.1.2/node_modules/@google-cloud/secret-manager/build/src/index.js
./src/lib/jwt-keys.ts
./src/app/api/internal/mint-token/route.ts

The generated build/protos/protos.js file contains both an AMD dependency on protobufjs/minimal and a CommonJS path through google-gax:

if (typeof define === 'function' && define.amd)
  define(["protobufjs/minimal"], factory);
else if (typeof require === 'function' && typeof module === 'object' && module && module.exports)
  module.exports = factory(require("google-gax/build/src/protobuf").protobufMinimal);

google-gax/build/src/protobuf.js does correctly re-export protobufjs/minimal, and google-gax@5.0.6 declares protobufjs:

google-gax@5.0.6 -> protobufjs ^7.5.3

However, under pnpm's isolated node_modules layout, @google-cloud/secret-manager can see google-gax, but it does not directly see protobufjs. Webpack/Next appears to statically process the AMD dependency string in protos.js and tries to resolve protobufjs/minimal from the Secret Manager proto module itself, instead of relying only on the CommonJS google-gax/build/src/protobuf path.

Expected behavior

A server-side Next.js/webpack build should not need the application package to add protobufjs explicitly just to bundle @google-cloud/secret-manager, since Secret Manager's runtime CommonJS path goes through google-gax, and google-gax owns the protobufjs dependency.

Ideally the generated Secret Manager proto output would not expose a direct protobufjs/minimal dependency to bundlers unless @google-cloud/secret-manager itself declares that dependency.

Workaround

Adding protobufjs explicitly to the consuming package fixes the Vercel/Next build:

{
  "dependencies": {
    "@google-cloud/secret-manager": "^6.1.2",
    "protobufjs": "^7.5.5"
  }
}

In our pnpm workspace, this made protobufjs/minimal visible to the application bundle and the auth service build passed again.

Why I think this is an upstream packaging/generation issue

The package metadata currently looks like this:

@google-cloud/secret-manager@6.1.2
  dependencies:
    google-gax: ^5.0.0

google-gax@5.0.6
  dependencies:
    protobufjs: ^7.5.3
    @grpc/proto-loader: ^0.8.0
    proto3-json-serializer: ^3.0.0

That dependency graph is fine for Node's CommonJS runtime path, but the generated define(["protobufjs/minimal"], factory) branch creates a direct-looking static dependency from the Secret Manager proto file. Bundlers can try to resolve that dependency from @google-cloud/secret-manager, where pnpm has not linked protobufjs because Secret Manager does not declare it directly.

Would you consider either removing/altering the AMD dependency emitted in generated proto files, or declaring protobufjs directly from packages whose generated output references protobufjs/minimal?

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