Skip to content

firebase preset emits a stub firebase-functions in .output/server/node_modules whose exports point to non-existent files (breaks firebase-tools v15 deploy) #4321

@yizumi1012xxx

Description

@yizumi1012xxx

Environment

  • Nitro (nitropack): 2.13.4
  • Node.js: 22.16.0 / 24.16.0
  • Nuxt: 4.4.7
  • Package manager: pnpm 11.5.2
  • nitro config:
    nitro: { preset: 'firebase', firebase: { gen: 2, nodeVersion: '22' } }

Reproduction

A minimal reproduction repo can be provided on request, but the broken artifact is observable from any firebase (gen2) preset build:

  1. Nuxt/Nitro app with nitro: { preset: 'firebase', firebase: { gen: 2, nodeVersion: '22' } }.
  2. nuxt build (or nitro build).
  3. Inspect the output:
    cat .output/server/node_modules/firebase-functions/package.json   # has an "exports" map
    ls  .output/server/node_modules/firebase-functions/lib            # empty — referenced files are absent
    node -e "require.resolve('firebase-functions', { paths: ['.output/server'] })"  # throws ERR_MODULE_NOT_FOUND
  4. Deploy with current firebase-tools (v15): firebase deploy --only functions --debug → aborts.

Describe the bug

The firebase preset writes .output/server/node_modules/firebase-functions/ as a stub consisting of only a package.json (plus an empty lib/ directory). The actual SDK code is bundled into server.mjs, but the stub package.json still carries an exports map copied from the real package:

{
  "exports": {
    ".": {
      "types": "./lib/v2/index.d.ts",
      "import": "./lib/esm/v2/index.mjs",
      "require": "./lib/v2/index.js"
    }
  }
}

None of those files are emitted, so the package is unresolvable: any consumer that does require.resolve('firebase-functions', { paths: [outputServerDir] }) follows the exports require/import condition to a missing file and throws ERR_MODULE_NOT_FOUND. In effect the preset emits a package whose exports advertise entry points it does not ship.

This now breaks deployment. firebase-tools v15 added a require.resolve('firebase-functions', { paths: [sourceDir] }) call in its node runtime delegate (findFunctionsBinary), so firebase deploy of a Nitro-built functions codebase crashes with An unexpected error has occurred.. It worked on firebase-tools v14, which did not resolve the SDK from the source dir.

I'll also raise the lack of try/catch on the firebase-tools side separately, but Nitro is producing a technically-invalid package (an exports map pointing to files it doesn't ship), which is the trigger.

Suggested directions (any one resolves it):

  • Don't write a node_modules/firebase-functions stub at all (the code is already bundled into server.mjs and isn't needed at runtime), or
  • Write the stub package.json without the exports field (so resolution falls back instead of advertising missing subpaths), or
  • Actually emit the files referenced by exports.

Happy to help with a PR once the preferred direction is decided.

Logs

i  functions: Loading and analyzing source code for codebase lp to determine what to deploy
Could not parse firebase-functions version '' into semver.
Could not find functions.yaml. Must use http discovery
Error: Cannot find module '<project>/.output/server/node_modules/firebase-functions/lib/v2/index.js'
    at createEsmNotFoundErr (node:internal/modules/cjs/loader:1437:15)
    at finalizeEsmResolution (node:internal/modules/cjs/loader:1426:15)
    at resolveExports (node:internal/modules/cjs/loader:657:14)
    at Function._findPath (node:internal/modules/cjs/loader:749:31)
    at Function._resolveFilename (node:internal/modules/cjs/loader:1387:27)
    at Function.resolve (node:internal/modules/helpers:145:19)
    at Delegate.findFunctionsBinary (firebase-tools/lib/deploy/functions/runtimes/node/index.js:101:33)
    at Delegate.spawnFunctionsProcess (firebase-tools/lib/deploy/functions/runtimes/node/index.js:131:30)
    at Delegate.serveAdmin (firebase-tools/lib/deploy/functions/runtimes/node/index.js:152:35)
    at Delegate.discoverBuild (firebase-tools/lib/deploy/functions/runtimes/node/index.js:192:41)

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