Skip to content

[Bug]: iPhone composer keeps the prompt text after it's sent #20982

Open

Description

@grahamfarrar

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/mobile

Steps to reproduce

Intermittent. It has happened a handful of times since updating.

  1. In the iPhone app, open a Claude thread. In the observed case a turn was running, so the send button showed the queue icon.
  2. Enter a longer prompt. It was dictated, but I don't know whether it went through the composer mic or the iOS keyboard mic.
  3. Press send.

Expected behavior

The message is sent and the composer clears.

Actual behavior

The message is sent. It shows in the timeline and the server records it once, a single message.updated event with createdBy: "user" and creationSource: "mobile". But the full text stays in the composer, and the send button stays active.

Pressing send again would send the same prompt a second time.

This looks like the reverse of #15129 and #17422. In those, the editor view and the draft snapshot get out of step in the other direction. Here, the draft seems to be cleared on send, but the iOS text view keeps showing the old text.

Impact

Moderate. It's easy to send a duplicate prompt, or to type a new message onto the end of the old text without noticing.

Version or commit

iPhone app 1.4.1. Server 0.1.0.

Environment

iPhone Air, connected over Tailscale to a self-hosted t3 serve 0.1.0 on macOS 26.6.2. Claude Agent provider, Opus 5.5.

Logs or stack traces

None collected. I have a screenshot showing the sent message in the timeline and the same text still in the composer.

Workaround

Clear the composer by hand after sending.

Activity

  1. juliusmarminge commented on Oct 17, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    We can't confirm this as a new bug yet. It fits one of two composer sync problems we already track:

    You said send stayed active. Please tell us:

    1. Whether pressing send again actually sent a duplicate.
    2. Whether you used the in-app mic or the keyboard mic.
    3. Whether the leftover text exactly matched what was sent.
  2. grahamfarrar commented on Oct 18, 2026

    @grahamfarrar
    Author
    1. No. I cleared the composer by hand each time, so no duplicate went out.
    2. I think it was the iOS keyboard mic, not the in-app mic.
    3. Yes, the full text exactly as sent.
  3. juliusmarminge commented on Oct 21, 2026

    @juliusmarminge
    Member

    Checked current main at 70e5e384da. The isolated server started and disposable thread data was seeded, but on-device verification is blocked: the fresh EAS iOS simulator build reported Failed to upload metadata to EAS Build / HTTP 400. No send attempt ran, so this does not establish whether main reproduces or fixes it.

    The related disabled-send reports describe a different symptom; keeping this open. If it happens again, please share a screen recording showing whether iOS keyboard dictation has fully stopped before Send, and whether the remaining text/send button clears after dismissing the keyboard. Please include the current iPhone app version and iOS version. Redact private prompt content.

  4. nabettu commented on Oct 28, 2026

    @nabettu
    Contributor

    Another reliable way to hit "text stays in the composer after send": uncommitted IME composition on iOS.

    Repro (Japanese kana keyboard): type 「たかな」 without converting/committing it, tap Send. The message is delivered once, but the composer still shows 「たかな」 and Send stays enabled. The leftover text is saved as the draft, so it is still there after leaving and reopening the thread.

    Cause: #17614 made applyControlledDocument in T3ComposerEditorView.swift skip every controlled update while marked text exists. The send-time clear arrives during the composition and is skipped; when the composition commits, the editor emits the old text back and it becomes the draft again. The same "native edit lands after the JS clear" shape as the autocorrection case in #16890 / #26452, but a different trigger.

    Fix in #22843: only defer while JS echoes the text being composed (the case #17614 protects); a different value such as the send clear commits the composition with change events suppressed and is applied. iOS only; Android already replaces text during composition.

  5. nabettu commented on Oct 29, 2026

    @nabettu
    Contributor

    Correction to my earlier comment: #22843 doesn't fix the IME case, so I've closed it. With logging on a device, the sent text comes back because the post-send blur commits the still-marked composition before the cleared draft reaches the editor, and that commit's change event refills the draft. The fix is suggested on #26452: #26452 (comment)

  6. grahamfarrar commented on Oct 29, 2026

    @grahamfarrar
    Author

    This may be my case too. I was dictating with the keyboard mic when it happened, and dictation also holds the text uncommitted until it finishes.

  7. nabettu commented on Oct 30, 2026

    @nabettu
    Contributor

    Thanks, that fits. Keyboard dictation keeps the text it's still recognizing uncommitted, the same way IME composition does. So I'd expect the same sequence: the send reads the draft and clears it, then the post-send blur finalizes the dictation, and that change event writes the sent text back into the now-empty draft.

    On a build with #26452 plus the change suggested in #26452 (comment), I tried sending in the middle of keyboard dictation, and the composer cleared as expected. That's only a quick check, so if you still see it once that lands, a note on the iOS version and whether dictation was still running when you tapped Send would help narrow it down.

  8. grahamfarrar commented on Oct 31, 2026

    @grahamfarrar
    Author

    Still happening today on server 0.1.6, iPhone app build 202, iOS 27.2 (Darwin 27.2.0).

    • Input was iOS keyboard dictation, sent while a turn was running.
    • The message went out once and shows in the timeline.
    • The composer kept the full text, with Send still active.
    • I didn't notice whether dictation had stopped before I tapped Send.

    This matches the post-send blur sequence described above, so I'll retest once #26452 lands.

    Image
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

    via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions