Skip to content

fix(auth): skip project config name assertion when using the Auth emulator#3142

Open
kyungseopk1m wants to merge 1 commit into
firebase:mainfrom
kyungseopk1m:fix/emulator-project-config-internal-assert
Open

fix(auth): skip project config name assertion when using the Auth emulator#3142
kyungseopk1m wants to merge 1 commit into
firebase:mainfrom
kyungseopk1m:fix/emulator-project-config-internal-assert

Conversation

@kyungseopk1m
Copy link
Copy Markdown

Closes #2461.

Thanks @nerder and @mexican-jack for the same-symptom reports on updateProjectConfig and password policy updates — both go through the endpoints touched here.

Summary

getProjectConfig() and updateProjectConfig() throw INTERNAL ASSERT FAILED: Unable to get/update project config when the Auth emulator is running. The emulator doesn't populate the resource name field on /config responses, and both endpoint validators require name to be a non-empty string.

This PR skips that assertion when useEmulator() is true so the call succeeds against the emulator. Production behavior is unchanged.

Behavior change

  • Emulator (FIREBASE_AUTH_EMULATOR_HOST set): getProjectConfig() / updateProjectConfig() resolve with whatever the emulator returns.
  • Production: identical to before. A backend response missing name still throws INTERNAL ASSERT FAILED.

The Identity Toolkit projects.getConfig / projects.updateConfig REST contract treats name as an output-only resource name that production always populates — the emulator just doesn't implement it.

Scope

The guard is limited to GET_PROJECT_CONFIG and UPDATE_PROJECT_CONFIG because those are the two endpoints with reproductions in the issue and its comments. Other validators in the same file (GET_TENANT, UPDATE_TENANT, OIDC/SAML config) follow the same pattern but have no emulator reports — leaving them out keeps the diff narrow.

Password policy updates (raised by @mexican-jack) go through updateProjectConfig internally, so this PR covers that case as well.

Implementation notes

The guard uses the existing useEmulator() helper at src/auth/auth-api-request.ts:2321 — the same one AuthResourceUrlBuilder (line 134), TenantAwareAuthResourceUrlBuilder (line 200), and AuthHttpClient (line 232) use to branch on the emulator. Same dynamic-read pattern as the rest of main.

Relationship to #3080

#3080 is open in the same area and captures the emulator host at init time instead of reading it on each call. This PR uses the dynamic useEmulator() read because that's what main does today. If #3080 lands first, I'll rebase and switch the validator guard to the captured value so the emulator semantics stay aligned.

Test coverage

test/unit/auth/auth-api-request.spec.ts adds a getProjectConfig and an updateProjectConfig describe block under the supportsTenantManagement branch. Each has three cases:

  • normal production response with name populated — strict callParams match (URL, method, body, headers, timeout) for regression coverage
  • production response missing name — still throws (covers the existing assertion)
  • response missing name with FIREBASE_AUTH_EMULATOR_HOST set — resolves, with a strict match against the emulator URL http://localhost:9099/identitytoolkit.googleapis.com/v2/projects/project_id/config[?updateMask=...] and the Bearer owner emulator headers

afterEach clears FIREBASE_AUTH_EMULATOR_HOST so emulator state doesn't bleed into other specs.

Verification

  • npm run lint — 0 errors.
  • npx mocha test/unit/auth/auth-api-request.spec.ts --require ts-node/register — 746 passing, 0 failing.
  • npm run test:unit — 6246 passing, 0 failing.

Diff: 2 files changed, +136 insertions, -1 deletion (10 LOC in src, the rest in test).

…lator

The Auth emulator does not populate the resource `name` field on its
/config responses, so getProjectConfig() and updateProjectConfig() throw
"INTERNAL ASSERT FAILED: Unable to get/update project config" against
the emulator. Skip the assertion in both validators when useEmulator()
is true. Production behavior is unchanged — a backend response missing
`name` still throws.

The guard reuses the existing useEmulator() helper, matching the same
dynamic-read pattern AuthResourceUrlBuilder and AuthHttpClient already
use to branch on the emulator.

Fixes firebase#2461.
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the GET_PROJECT_CONFIG and UPDATE_PROJECT_CONFIG response validators in src/auth/auth-api-request.ts to skip the name field assertion when running against the Auth emulator. Additionally, it adds comprehensive unit tests in test/unit/auth/auth-api-request.spec.ts to verify the behavior of getProjectConfig and updateProjectConfig under both standard and emulator environments. I have no feedback to provide.

@lahirumaramba lahirumaramba self-assigned this May 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Got 'INTERNAL ASSERT FAILED: Unable to get project config' error when use Emulator

2 participants