Team Chat dead-letter recovery (re-file failed scheduled messages)
Status: Server-side Cloud Function is deployed and complete. No UI surface exists yet (in-development, no feature flag).
What it is
Status: Server-side Cloud Function is deployed and complete. No UI surface exists yet (in-development, no feature flag).
When a scheduled Team Chat message fails to deliver after exhausting its retry budget (MAX_DELIVERY_ATTEMPTS), it is moved to a dead-letter collection (scheduledMessagesDeadLetter) rather than being silently lost. A production-grade Cloud Function (teamChatRefileScheduledSend) can re-file a dead-lettered message back into the live scheduled queue with a fresh retry budget.
The server-side recovery path is 100% built. What is missing is a UI surface in the renderer that lets users:
- Discover that a scheduled message was dead-lettered
- Trigger a re-file (which calls the existing Cloud Function)
Where to find it
The server side is live with no interface yet; what is planned is an indicator in the scheduled-messages sidebar view.
How it behaves
How the re-file works (server side)
The teamChatRefileScheduledSend HTTPS relay (Firebase Cloud Function):
- Authenticates the caller (Firebase ID token)
- Verifies the caller is the message author and an active org/workspace member
- Reads the dead-letter doc inside a Firestore transaction
- Validates the doc shape (guards against corrupted data propagation)
- Atomically moves it back to
{channelPath}/scheduledMessages/{id}withdeliveryAttemptsreset to 0 - Deletes the dead-letter doc
The move is atomic (set + delete in one transaction), idempotent (same-id overwrites safely), and author-gated (you can only re-file your own messages).
Security model
Mirrors teamChatSendMessage:
- Firebase ID token auth (Authorization: Bearer)
- Author gate: only the message author can re-file
- Membership gate: must still be an active member
- Soft-delete gate: refuses re-file into a deleted workspace
- Disabled-account gate
- Channel path validation (F105 shape check)
What is needed for UI completion
- A query/listener on
scheduledMessagesDeadLetterto detect when dead-lettered messages exist - An indicator in the scheduled messages sidebar view (e.g. a badge or a separate section)
- A "Re-file" or "Retry" action button per dead-lettered message that calls the Cloud Function
- Error/success feedback (toast or inline status)
The Cloud Function endpoint is ready to call: POST /t/team-chat-refile-scheduled-send with body { channelPath, deadLetterId }.
For agents
Architecture
- Dead-letter collection:
{root}/channels/{channelId}/scheduledMessagesDeadLetter/{id} - Live queue:
{root}/channels/{channelId}/scheduledMessages/{id} - Cloud Function:
teamChatRefileScheduledSend(HTTPS relay,POST, bearer auth) - Hosting rewrite:
/t/team-chat-refile-scheduled-send - Source:
firebase/functions/src/team-chat/scheduled-send-refile.ts
Notes for agents
- The dead-letter WRITE side (moving failed messages to the DLQ) is also complete and shipped.
- The server validates the dead-letter doc shape before trusting it (
validateDeadLetterShape). - Re-filing resets
deliveryAttemptsto 0, giving the message a fresh retry budget. - No UI surface or feature flag exists yet for dead-letter visibility or re-filing.
- Related: team-chat.md (scheduled send section), team-chat-desktop-contract.md.
Related
- team-chat.md — the messaging surface the re-file serves.
- team-chat-api-platform.md — the other planned Team Chat capability.
- team-chat-export.md — the other planned Team Chat capability.
Last verified 2026-09-23