Skip to content

CI: test/firestore.test.tsx flakes on Node 24 with RESOURCE_EXHAUSTED on the Listen stream #776

Description

@tyler-reitz

test/firestore.test.tsx fails intermittently on Node 24 only, and passes on re-run with no code change. It has fired three times in two days on PRs that cannot plausibly cause it, including a lockfile-only dependency bump.

Every occurrence costs a full CI cycle and a manual re-run, and it trains reviewers to ignore red runs.

Signature

AssertionError: expected 'loading' to deeply equal 'success'
Expected: "success"

Alongside, on the same run:

@firebase/firestore: Firestore (11.10.0): GrpcConnection RPC 'Listen' stream 0x79e9f196 error.
Code: 8 Message: 8 RESOURCE_EXHAUSTED: Received message larger than max (3540390128 vs 4194304)

⚠️ This second error is not the cause. It did not appear in any local reproduction of the failure. Local failures are waitFor hitting its 1000ms default, at 1058ms and 1142ms, plus one 120s hang. Do not start from the "corrupted length prefix" theory. See the investigation comment.

Occurrences

Date PR What it touched
2026-08-04 #774 package-lock.json only (postcss bump)
2026-08-03 #770 src/ import specifiers only
2026-08-03 (earlier run) no source changes

Node 22 passes every time. In the #774 run, 8 of 9 test files passed.

The two tests that fail

Both are in test/firestore.test.tsx:

  • useFirestoreDocData > returns undefined if document does not exist (~line 100)
  • useFirestoreDocOnce > works when the document does not exist, and does not update when it is created (~line 174)

They are the two tests that read a document that does not exist. That is the shared property, and it is more specific than "these tests are slow". A non-existent document cannot be answered from the local cache, so the hook stays in loading until the Listen stream confirms absence. That round trip is what exceeds waitFor's 1000ms budget, so these two are the first to fail whenever the stream is slow.

Suspected cause

Updated after investigation. Full data in this comment.

Reproduced locally at a 13.6% failure rate on Node 24, 0% on Node 22. The current suspect is @grpc/grpc-js 1.9.16, which @firebase/firestore pins via ~1.9.0 and which predates Node 24. Forcing 1.14.4 through overrides gave 0 failures in 38 runs.

This is suggestive, not proven. The pre-registered 30-runs-per-arm comparison came back p = 0.12, which is not significant; pooling all batches gives p = 0.02, but that pooling was chosen after seeing the results.

Two constraints on any fix:

  1. Upgrading firebase does not help. Every published @firebase/firestore through 4.17.0 still pins ~1.9.0. An overrides entry is the only lever in this repo.
  2. An override makes CI test a @grpc/grpc-js consumers do not get. If 1.9.16 is genuinely unwell on Node 24, the bug still reaches anyone running reactfire server-side there, and the real fix belongs upstream in firebase-js-sdk.

The RESOURCE_EXHAUSTED message is the strongest lead. Ruled out, see the note under Signature.

Suggested scope

Apply the overrides bump and let CI accumulate evidence across the next few weeks of PRs, which is a stronger signal than more local batch runs.

If the flake persists, the grpc-js theory is wrong and the 120s hang is the next thread: a raised waitFor timeout would not have saved that run, so "just bump the timeout" is not a sufficient fallback.

Note for reviewers

Until this is fixed: a red Test Node.js 24 on a PR touching no source is probably this. Re-run before investigating, and say so in the PR thread rather than leaving a red run unexplained. Do not conclude anything from a single run in either direction, since one pass does not clear a branch and one failure does not condemn it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions