Search code examples
node.jsfirebasegoogle-cloud-functionsfirebase-tools

Firebase Functions "cannot determine backend specification"


I started intermittently receiving this error

⬢ functions: Failed to load function definition from source: FirebaseError: User code failed to load. Cannot determine backend specification

when starting the emulator. Reports of this on the internet speculate about a wide range of things but no root cause was known, so I've been just restarting constantly until the error doesn't throw. Now, it's 100% of the time and my development has screeched to a halt. After hours and hours of switching going down various guess-and-check rabbit holes, I'm at a loss.

firebase-tools version:

$ firebase --version
13.17.0

Here is a minimum reproducible version of functions/index.js:

const admin = require("firebase-admin/app");
admin.initializeApp();

const functions = require("firebase-functions/v1");

exports.created = functions.auth.user().onCreate(async (user) => {
  const email = user.email;
  console.log(email);
  return;
});

And the contents of functions/package.json:

{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "lint": "eslint .",
    "serve": "firebase emulators:start --only functions",
    "shell": "firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log"
  },
  "engines": {
    "node": "18"
  },
  "main": "index.js",
  "private": true,
  "dependencies": {
    "firebase-admin": "^12.4.0",
    "firebase-functions": "^6.0.1",
    "nodemailer": "^6.9.15"
  }
}

When starting the emulator with the --debug flag, this precedes the error in the log:

Failed to find version of module node: reached end of search path src/functions/node_modules
✔  functions: Using node@18 from host. 
Could not find functions.yaml. Must use http discovery
Found firebase-functions binary at 'src/functions/node_modules/.bin/firebase-functions'
Serving at port 8872

⬢  functions: Failed to load function definition from source: FirebaseError: User code failed to load. Cannot determine backend specification

Update: After further debugging, it seems that when the emulator starts, it attempts to serve up the functions code via this:

node src/functions/node_modules/.bin/firebase-functions src/functions

My current best current guess is that there is a bug in firebase-tools where it no longer creates a functions.yaml (perhaps an artifact of a past version) or in firebase-functions where node crashes for some reason and thus does not serve the functions code within the 10s timeout expected by firebase-tools.


Solution

  • I believe I've found the source of the problem, and a work-around, although this should really be solved on Firebase's side.

    I develop on Windows using WSL2; my functions code resides on Windows and I use vscode + WSL to develop on WSL2-Ubuntu. The emulated /mnt/ in Linux to access the code on the Windows side is slower than the native Linux file system. This causes bulky filesystem operations to take longer than otherwise possible in modern computers with SSDs.

    firebase-tools's emulator kicks off firebase-functions to load your functions code and it internally allows up to 10s for firebase-functions to get its work done and respond.

    firebase-functions is seemingly doing something that takes it far longer to get its work done than one would expect. The timer effectively starts:

    Serving at port XXXX
    

    and has completed:

    ✔  functions: Loaded functions definitions from source: ...
    

    or failed after 10s:

    ⬢  functions: Failed to load function definition from source: ...
    

    The work-around in my case is to move my code to the "local" WSL2-Ubuntu filesystem. This allows firebase-functions to get its work done within the 10s cut-off.

    What I would like to see Firebase fix here, is to:

    • extend that 10s timeout in firebase-tools as total failure is certainly not preferable to providing a response within 10s
    • improve the efficiency of firebase-functions's critical path to loading the code... I'm guessing it may be doing something unnecessary with the extensive node-modules folder that is within the src/functions path provided to it.

    I have wasted 5 days worth of development time on this; I hope all of these clues save the next person some debugging time. If the slower file system I/O doesn't apply to your environment, consider any other factor that can affect firebase-functions responding on its port in time, such as VPNs routing away local traffic or any other abnormal network configurations, or perhaps abnormal file/dir permissions in your functions code, etc.