← Back to PRs

#15564: fix: webchat messages disappear during concurrent session activity

by Automatedcapitalist open 2026-02-13 16:13 View on GitHub →
app: web-ui gateway stale size: S
## Summary - **CIDR support for `gateway.trustedProxies`**: `isTrustedProxyAddress` did exact string matching, so CIDR entries like `100.64.0.0/10` never matched real IPs. Connections through a reverse proxy triggered "Proxy headers detected from untrusted address" warnings and unnecessary WebSocket reconnects that cleared chat state. - **Optimistic message persistence in webchat UI**: When a user sends a webchat message, the UI adds it to `chatMessages` optimistically. If another run on the same session completes (Telegram, cron) or the WebSocket reconnects, `loadChatHistory` replaces all in-memory messages with server data that doesn't yet include the pending message — making it vanish. Fix tracks the optimistic message in a module-level variable and re-appends it after server refreshes until the server history catches up. ## Test plan - [ ] Send a webchat message while a Telegram message is being processed on the same agent session — user message should remain visible - [ ] Trigger a WebSocket reconnect (e.g. restart gateway) while a webchat message is pending — message should reappear after reconnect - [ ] Configure `trustedProxies` with a CIDR range (e.g. `127.0.0.0/8`) and connect through a reverse proxy — no "untrusted proxy" warning - [ ] Verify exact-IP entries in `trustedProxies` still work (backwards compatible) - [ ] Verify optimistic message clears after agent responds (final event) 🤖 Generated with [Claude Code](https://claude.com/claude-code) — AI-assisted, tested on a live OpenClaw gateway instance <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR addresses two sources of “disappearing webchat messages”: - **Gateway**: `isTrustedProxyAddress` now supports CIDR entries in `gateway.trustedProxies`, so reverse proxies configured with ranges (e.g. `100.64.0.0/10`) can be recognized and won’t trigger the “untrusted proxy headers” path that leads to reconnect churn. - **Control UI / webchat**: `loadChatHistory` preserves a single optimistic user message across history refreshes/reconnects by re-appending it until server history appears to include a user message at/after the optimistic timestamp. <h3>Confidence Score: 3/5</h3> - Moderate confidence; one user-visible edge case should be fixed before merge. - Core changes are small and locally-scoped, but the optimistic-message persistence adds a new global pending state that is not cleared on send failures, which can leave stuck/duplicate UI messages after a refresh/reconnect. - ui/src/ui/controllers/chat.ts <sub>Last reviewed commit: edc4fe9</sub> <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> <!-- /greptile_comment -->

Most Similar PRs