Skip to content

Functions deploy fails with 403 on Extensions API when no extensions are used #9987

@devotedabilities

Description

@devotedabilities

Description

firebase deploy --only functions fails with a 403 error on the Firebase Extensions API (firebaseextensions.googleapis.com) even when the project uses zero extensions.

Steps to Reproduce

  1. Create a Firebase project with Cloud Functions (2nd gen, Node 22) and no extensions
  2. Ensure firebase.json has no extensions key
  3. Ensure no code imports from firebase-functions/extensions
  4. Run firebase deploy --only functions

Expected Behavior

Deploy succeeds — extensions check is skipped when no extensions are defined.

Actual Behavior

i  extensions: ensuring required API firebaseextensions.googleapis.com is enabled...
Error: Request to https://firebaseextensions.googleapis.com/v1beta/projects/<project>/instances?pageSize=100&pageToken= had HTTP Error: 403, The caller does not have permission

Root Cause

In lib/deploy/functions/prepare.js line 70:

if (Object.values(wantBuilds).some((b) => b.extensions)) {

The firebase-functions SDK runtime loader always includes an extensions key in the build output — even when no extensions are defined, it returns extensions: {}. Since {} is truthy in JavaScript, the check passes and prepareDynamicExtensions is called, which then hits listInstances on the Extensions API.

Fix

Change the check to also verify the extensions object is non-empty:

if (Object.values(wantBuilds).some((b) => b.extensions && Object.keys(b.extensions).length > 0)) {

Environment

  • Firebase CLI: 15.8.0 (also reproduced on 13.x and 14.x)
  • firebase-functions: ^6.3.0
  • Node: 22
  • OS: macOS (Darwin 25.2.0)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions