Skip to content

Production Firestore getAll crash blocks signing pages during auth refresh

Why (owner, 2026-06-28)

"But the sign WOPC link also has the same issue: https://eop.theestablishers.com/wopc/sign/79DkCWLu6btYB4S41nLX ... Error: An error occurred in the Server Components render."

The WOPC and IR56M signing links were both showing the generic production Server Components error page after login. That made the signing link look broken even when the signing request itself existed and the assigned-director authorization logic was correct.

Diagnosis

The NAS log showed the real exception behind digest 1701398211:

TypeError: Right-hand side of 'instanceof' is not an object
    at b.validateDocumentReference
    ...
    at V.getAll

The only app-side Firestore.getAll(...) call path is lib/accounting/bankSyncSnapshot.server.ts. It bulk-reads transaction snapshot document references during the sync backfill helper. In the deployed standalone bundle, Firestore's getAll reference validator can trip over the bundled DocumentReference class and throw before the route finishes rendering. The same request also logs [auth] Failed to refresh access profile because NextAuth profile refresh is running during page render; WOPC is the page where the symptom is visible, not the root cause.

What shipped

lib/accounting/bankSyncSnapshot.server.ts no longer calls db.getAll(...refs). It reads the same references through Promise.all(refs.map((ref) => ref.get())) for both snapshot existence checks and live transaction reads.

This keeps the same behavior but avoids Firestore's problematic getAll validator in production.

Verification

  • βœ… Attestation (Codex local session): read AGENTS.md; checked the board by scope, not UID β€” no existing task covered the production Firestore getAll crash. Tracking T-130.
  • Source: Codex local session Β· /Users/gutchumi/dev/ArtifactoftheEstablisher-codex-wopc-pdfjs
  • Reproduced from NAS logs after the WOPC signing link failed.
  • Local probe showed the alternative ref.get() path succeeds.
  • git diff --check clean.
  • NODE_OPTIONS=--max-old-space-size=4096 npx tsc --noEmit clean.

Blast Radius

Transaction import/sync snapshot backfill only. No WOPC or IR56M signing data shape changes. The signing pages benefit because this removes the shared server runtime crash that was surfacing during auth/page render.

Follow-up β€” first fix was incomplete (2026-06-28)

  • βœ… Attestation (Codex local session): read AGENTS.md; checked the board by scope, not UID β€” this remains the same production signing-link Firestore crash, so T-130 is extended rather than opening a duplicate.
  • Source: Codex local session Β· /Users/gutchumi/dev/ArtifactoftheEstablisher-codex-wopc-pdfjs
  • Owner evidence (verbatim, 2026-06-28): "Still doesn't work" with the Chrome log showing GET https://eop.theestablishers.com/ir56m/sign/... 500 and the production Server Components render error.
  • Corrected diagnosis: after the first deployment, the NAS was definitely running the latest image, but fresh logs still showed the same validateDocumentReference β†’ V.getAll stack. Inspecting the compiled chunk showed the call was no longer an app-level db.getAll(...); it was DocumentReference.get() internally delegating to this._firestore.getAll(this). A direct Node probe inside the same container could read Firestore normally, which points to Next's server bundle breaking the Firestore SDK class identity, not bad credentials or missing data.
  • Second fix: next.config.ts now externalizes @google-cloud/firestore and firebase-admin via serverExternalPackages, so production uses the installed Node packages instead of bundling Firestore into Next server chunks. The critical auth/signing entry reads were also changed from docRef.get() to where(FieldPath.documentId(), '==', id).limit(1).get(): user profile refresh, WOPC signing request lookup, IR56M signing request lookup, and WOPC pending signature image lookup.
  • Verification before deploy: git diff --check clean and NODE_OPTIONS=--max-old-space-size=4096 npx tsc --noEmit clean.
  • Blast radius: Next server build behavior for Firestore/admin SDK imports, plus single-document read helpers for RBAC profile refresh and WOPC/IR56M signing requests. Firestore document shapes and signing request state-machine writes are unchanged.

2026-06-29 β€” review confirmation + footgun guard added (Accounting (Infrastructure))

  • βœ… Attestation (Accounting (Infrastructure)): read AGENTS.md; appending a signed note to Codex's task (not editing the prose above) after an owner-requested review of the Codex commits.
  • Source (edit): Accounting (Infrastructure) Β· https://claude.ai/code/session_015P6KzVYsQCLgEmUjR9bMwM
  • Reviewed clean: independently verified this fix β€” serverExternalPackages is the correct key for Next 15.5.19 (the Next-14 experimental.serverComponentsExternalPackages would have silently no-op'd), placed top-level and surviving the Sentry/bundle-analyzer wrappers; since the Dockerfile ships full node_modules + next start the externalized packages resolve at runtime. The five docRef.get() β†’ where(documentId()).limit(1) swaps are semantically faithful (.empty guarded, .docs[0] read, direct collections). getAll β†’ Promise.all(refs.map(r => r.get())) preserves order + missing-doc semantics.
  • Hardening added (commit in I-016): the signing write/transaction paths (tx.get / .update / .create in the WOPC + IR56M signing repos) were NOT converted by this task and still rely on the serverExternalPackages externalization to keep Firestore's class identity intact β€” so a DO NOT REMOVE comment was added in next.config.ts cross-referencing T-130, to stop a future edit from dropping it on the assumption that "the query rewrites fixed signing" (they only fixed reads). No behavior change to this task's fix.

Commit index (backfilled 2026-07-01, best-effort Β· Coaching (Diagnostic))

Candidate related commits, auto-backfilled from git on main: commits whose message references this task's UID or a PR number it cites. Not verified β€” this squash-merged history can't yield a precise per-task list, so rows tagged (mentions only) name the task in passing (may be tangential) and untagged work commits may be missing. Treat as a starting point: verify, prune tangential rows, and append any real ones per the AGENTS.md "record every related SHA" policy.

  • 733eab9 2026-06-29 β€” fix(I-016): voided WOPC could download as a "sealed" signed PDF + hardening (mentions only)
  • 0261345 2026-06-29 β€” fix: green main (stale WOPC pdf tests) + extend T-130 read pattern to profile writes
  • a56f444 2026-06-29 β€” docs: refresh Accounting (Infrastructure) session ledger + T-130 review note
  • e588e7e 2026-06-29 β€” Merge pull request #817 from girafeev1/claude/post-codex-bug-sweep (mentions only)