ng add @angular/fire stops during setup when firebase-tools 15.26.0 or later runs non-interactively. Running ng add yourself in an ordinary terminal is not affected.
Reproduction
In an Angular 21 application with firebase-tools 15.28.1, run ng add @angular/fire@next from a terminal where AI_AGENT or CLAUDECODE is set, for example one driven by Claude Code, and pick any feature. Setup prints:
Using firebase-tools version 15.28.1
Cannot read properties of undefined (reading 'email')
The same run with those variables unset reaches the account, project and app questions.
Cause
firebase-tools 15.26.0 turns on non-interactive mode when it detects an AI agent (firebase/firebase-tools#10856). In that mode login() now starts a remote sign-in and returns undefined instead of the signed-in account (firebase/firebase-tools#10777). Earlier versions threw an error in that mode instead.
userPrompt in src/schematics/setup/prompts.ts:110 reads defaultUser.email from that return value, which is the error above.
src/schematics/setup/index.ts:94 gets undefined the same way. With line 110 fixed alone, setup then calls login.use for an account that is already in use, which fails with Already using account ... for this project directory.
ng deploy reads user.email from login() in src/schematics/deploy/actions.ts:560.
Who is affected
firebase-tools runs non-interactively when stdin is not a terminal, or when it finds one of a list of variables, such as AI_AGENT, CLAUDECODE, CURSOR_AGENT or COPILOT_GITHUB_TOKEN, in the environment.
- An AI coding tool that runs
ng add or ng deploy for you.
- A terminal that inherited one of those variables, for example an editor started from inside an agent session, or a shell profile that exports
COPILOT_GITHUB_TOKEN for the Copilot CLI.
- Every published AngularFire release has the crashing code, including
latest (20.1.0) and next (21.0.0-rc.1).
- Current Cursor (3.22.7) and VS Code (1.138.0) set them only in the terminals their agents use, not in the terminals you type in.
- firebase-tools 15.25.1 and earlier, including 14.x, return the account in a terminal.
Directions for a fix
login() returns the signed-in account in agent mode when it is passed interactive: true, an option firebase-tools applies after its agent check. Where no account may be signed in yet, an undefined return should mean "no account" rather than be read from.
ng add @angular/firestops during setup when firebase-tools 15.26.0 or later runs non-interactively. Runningng addyourself in an ordinary terminal is not affected.Reproduction
In an Angular 21 application with firebase-tools 15.28.1, run
ng add @angular/fire@nextfrom a terminal whereAI_AGENTorCLAUDECODEis set, for example one driven by Claude Code, and pick any feature. Setup prints:The same run with those variables unset reaches the account, project and app questions.
Cause
firebase-tools 15.26.0 turns on non-interactive mode when it detects an AI agent (firebase/firebase-tools#10856). In that mode
login()now starts a remote sign-in and returnsundefinedinstead of the signed-in account (firebase/firebase-tools#10777). Earlier versions threw an error in that mode instead.userPromptinsrc/schematics/setup/prompts.ts:110readsdefaultUser.emailfrom that return value, which is the error above.src/schematics/setup/index.ts:94getsundefinedthe same way. With line 110 fixed alone, setup then callslogin.usefor an account that is already in use, which fails withAlready using account ... for this project directory.ng deployreadsuser.emailfromlogin()insrc/schematics/deploy/actions.ts:560.Who is affected
firebase-tools runs non-interactively when stdin is not a terminal, or when it finds one of a list of variables, such as
AI_AGENT,CLAUDECODE,CURSOR_AGENTorCOPILOT_GITHUB_TOKEN, in the environment.ng addorng deployfor you.COPILOT_GITHUB_TOKENfor the Copilot CLI.latest(20.1.0) andnext(21.0.0-rc.1).Directions for a fix
login()returns the signed-in account in agent mode when it is passedinteractive: true, an option firebase-tools applies after its agent check. Where no account may be signed in yet, anundefinedreturn should mean "no account" rather than be read from.