Skip to content

Mobile: delivered messages leave a permanent ghost "Queued" duplicate (host ledger balanced, cache at 0) #14641

Closed

Description

@aproposdev

Summary

On Orca Mobile (iOS), a message sent while the desktop agent is mid-turn renders twice: once as a normal delivered message, and again below it as a grey bubble labelled "Queued". The message is delivered and the agent acts on it — the grey duplicate is spurious. They accumulate, one per message sent while the agent is busy, and survive app restarts.

What makes this more than cosmetic noise

The queued state appears to be client-side and has no reconciliation path, so nothing on the host can clear it. Verified on the host while two ghost bubbles were visible on the phone:

1. The session's own queue ledger is balanced. Replaying queue-operation records from the Claude Code transcript for the affected session:

enqueue 11 · remove 9 · dequeue 2  → outstanding 0

2. queuedMessageCount in the host cache is 0 for that session.
~/Library/Application Support/orca/ai-vault/session-parse-cache.json → entries[i][1].session.queuedMessageCount == 0.

3. The two ghosted messages produced no queue-operation records at all. They were delivered directly, never enqueued host-side — yet the client still painted "Queued" on both. That points at optimistic client-side state that is only reconciled by a queue lifecycle event which, on this path, never occurs.

Related: stale queuedMessageCount in the parse cache

Separately, session-parse-cache.json accumulates nonzero queuedMessageCount values for sessions whose real ledger balances to 0 (observed: counts of 4, 1, 1 across three sessions). Because the value is cached rather than recomputed, it persists across app and phone restarts. Zeroing the file by hand does not stick — the running app rewrites it from memory.

Reading the desktop bundle, the count is derived by replaying records:

if (record.type === "queue-operation") {
  if (record.operation === "enqueue" && content.trim().length > 0) queuedMessageCount++;
  else if (record.operation === "remove" || record.operation === "dequeue") queuedMessageCount--;
}

If the cache is not invalidated when a session's records change, a count that goes stale stays stale. Recomputing on read, or invalidating on transcript mtime change, would fix that half.

Reproduction

  1. Start an agent session on a desktop host; attach Orca Mobile to it.
  2. Give the agent a long-running task so it is mid-turn.
  3. From the phone, send a message while "Agent is working" is displayed.
  4. The message is delivered and acted on; a grey "Queued" duplicate also appears and remains.
  5. Repeat — one additional ghost per message. They persist across force-quit of the desktop app and across Orca restarts.

Environment

  • Orca desktop 1.4.182, macOS 26.5.2, Apple Silicon
  • Orca Mobile (iOS 26), phone connected over Orca Relay
  • Agent: Claude Code

What would help

  • Reconcile or expire client-side queued entries when the corresponding message is delivered through a non-queue path.
  • Recompute queuedMessageCount when the session transcript changes, rather than trusting the cached value.

Activity

  1. OrcaWin commented on Aug 15, 2026

    @OrcaWin
    Collaborator

    Related, not closing: #14262 (stale “queued” bubbles after glued rapid sends) was closed by #14663 (desktop) and #14665 (mobile).

    This report’s host-ledger-balanced / never-enqueued diagnosis looks like a different reconciliation path, so leaving it open. Worth a retest on a build that includes those two PRs in case the ghosts were the same client-side pending bubbles.

  2. AmethystLiang commented on Aug 16, 2026

    @AmethystLiang
    Contributor

    thanks for reporting. looking into it

  3. lookerlukal commented on Aug 24, 2026

    @lookerlukal

    Reproduces on Android as well — the original report is iOS, so this is not iOS-specific.

    Environment

    • Viewer: Orca Android client (paired device)
    • Host: Orca v1.4.188 on Windows 11 (10.0.26100)

    Symptom

    Messages sent from the phone frequently render twice in the mobile chat view — the delivered message plus a duplicate bubble below it — matching the ghost-"Queued" duplication described here. The agent does receive and act on the message; the duplicate is display-only. The accumulated duplicates make the conversation genuinely hard to follow.

  4. added theissue type on Sep 19, 2026
  5. AmoabaKelvin commented on Oct 21, 2026

    @AmoabaKelvin
    Collaborator

    Fixed by #31204, which is on main but not in a release yet. When Claude picks up a message mid-turn, it records it only as a queued_command entry and writes no normal user message. Orca's transcript reader skipped those entries, so the phone's temporary bubble had nothing to match and stayed below the real conversation. The reader now turns them into user messages, so the bubble goes away and the message shows where Claude read it, on iOS and Android, once your desktop or orca serve host updates to the release after v1.4.235. If you still see duplicates after updating, please reopen with the agent and host version.

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingmobile

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions