Skip to content

bug: message is silently lost when sending fails (e.g. network offline) #267

Description

@ebifrier

Problem

When sending a chat message fails (network offline, server unreachable, or a non-2xx response), the message silently disappears. The input is cleared, the optimistic user message flashes and is removed, no error is shown, and the text is gone. The only trace is an unhandled TypeError: Failed to fetch in the console.

Steps to reproduce

  1. Open a chat and type a message (optionally attach a file).
  2. Make the request fail, e.g. DevTools → Network → Offline, or stop the server.
  3. Press Enter.

Actual: the message appears for a moment, then vanishes; the input and attachments are empty; no toast. For a new chat the tab title keeps the first 40 characters of the lost message.

Expected: an error is shown and the message (and attachments) stay in the input so it can be re-sent.

Root cause

In ChatPanel.svelte send():

  • inputText = '' and chatInputEl.clearUploads() run before apiSendMessage is awaited.
  • The catch block only removes the optimistic message and rethrows. Nothing restores the draft and no toast is shown.
  • ChatInput calls onsend() without awaiting, so the rethrown error becomes an unhandled rejection and never reaches the user.
  • The streaming/queue branch has the same problem (its catch only logs).

Proposed fix

  • Capture the untransformed draft text and the attached files before sending.
  • On failure, restore both, reset currentMessageId, and reset the new-chat tab label.
  • Replace throw e with toast.error(...), matching how compact/fork failures are reported. ApiError messages from the server are shown as-is; other failures (network) use a new chat.sendFailed string.
  • Apply the same restoration in the queue branch.
  • ChatInput gets a small restoreUploads() counterpart to clearUploads().

Deliberately minimal: no retry button or "failed" marker on the message; happy to adjust if you prefer a different UX.

Verification

Playwright (headless Chromium) against a local build, aborting POST /api/chats with internetdisconnected:

before after
input after failed send empty text restored
toast none "Failed to send message"
new-chat tab title first 40 chars of the lost message "New Chat"
unhandled rejection yes no

Additional context

Implemented on a fork (4 files, +20/-3):
main...ebifrier:computer:fix/keep-message-on-send-failure

Related but different cause: #262 (prompt deleted when moving the window) does not involve sending.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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