firebase / firebase/firebase-js-sdk
linkWithPopup throws auth/multi-factor-auth-required after successful link, getMultiFactorResolver fails with auth/argument-error
- Dominant language
- TypeScript
- Stars
- 5.1k
- Forks
- 1k
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 37
Description
### Operating System
macOS (26.2 (25C56))
### Environment (if applicable)
Safari (Version 26.2 (21623.1.14.11.9))
### Firebase SDK Version
Tested on both 12.6.0 and 12.8.0 - same behavior
### Firebase SDK Product(s)
Auth
### Project Tooling
React SPA with Vite
### Detailed Problem Description
#### What I was trying to achieve
Link a federated provider (Microsoft) to an existing user account that has Phone MFA enabled, using `linkWithPopup()`.
#### What actually happened
1. `linkWithPopup()` throws `auth/multi-factor-auth-required` error
2. Attempting to handle the error with `getMultiFactorResolver(auth, error)` fails with `auth/argument-error`
3. However, checking `currentUser.providerData` reveals the provider WAS successfully linked
#### Console output (Firebase 12.8.0)
```
Error code: auth/multi-factor-auth-required
Error customData: {_serverResponse: Object, appName: "[DEFAULT]"}
Error serverResponse: {
federatedId: "http://microsoft.com/...",
providerId: "microsoft.com",
email: "user@example.com",
emailVerified: true
}
getMultiFactorResolver FAILED: "auth/argument-error"
Provider IDs after reload: ["microsoft.com", "password"]
Was linked: true
```
#### Key observations
- The `_serverResponse` contains the successfully linked federated identity, confirming the link completed on the
server
- The error doesn't contain valid MFA resolver information (hence `getMultiFactorResolver` fails)
- Same behavior on both 12.6.0 and 12.8.0
#### Expected behavior
Either:
1. `linkWithPopup()` should resolve successfully since the link completes, OR
2. If MFA verification is required, the error should contain valid resolver information
#### Current workaround
We reload the user and check if the provider was linked. This is brittle - if Firebase changes timing (throws error
before link completes), it would break.
#### Related
- FlutterFire #9402 - Similar issue fixed for Flutter SDK:
> "properly propagate the FirebaseAuthMultiFactorException for all reauthenticate and link methods"
#### Additional context
- Tested on localhost (127.0.0.1) development environment
- Not yet verified if the issue reproduces on production domains
### Steps and code to reproduce issue
```
// Prerequisites:
// 1. User account with email/password + Phone MFA enabled
// 2. User is signed in and has completed MFA verification
import { getAuth, getMultiFactorResolver, OAuthProvider, linkWithPopup } from 'firebase/auth';
const auth = getAuth();
const currentUser = auth.currentUser;
const provider = new OAuthProvider('microsoft.com');
try {
await linkWithPopup(currentUser, provider);
console.log('Link succeeded');
} catch (error) {
console.log('Error code:', error.code);
// Output: "auth/multi-factor-auth-required"
// Attempting to handle MFA as documented
try {
const resolver = getMultiFactorResolver(auth, error);
console.log('Resolver:', resolver);
} catch (mfaError) {
console.log('getMultiFactorResolver failed:', mfaError.code);
// Output: "auth/argument-error"
}
// Check if link actually succeeded despite the error
await currentUser.reload();
console.log('Provider IDs:', currentUser.providerData.map(p => p.providerId));
// Output: ["microsoft.com", "password"] - link DID succeed!
}
```
Contributor guide
Assessment
This issue has not been assessed yet.