Skip to content

Same remote machine connected via Tailscale + LAN is treated as two servers, duplicating threads and splitting message updates #66

@jelenv

Description

@jelenv

My prompt to codex (gpt-5.4 high) to investigate this:

Note

I noticed there are bugs when you connect to a remote via tailscale and at the same time local LAN. I connected to 2 IP addresses but its one machine. When you are connected like this, it happens that the application litter does not show properly the threads. For example it shows some threads twice or all of them twice and when you send a message in a thread it can happen that the message is not displayed in this thread but it will be displayed in the duplicate one. Please investigate and write me an issue which I can report to the author on GitHub.

What follows is output from codex, edited by me:

Summary

If the same remote machine is reachable both over Tailscale and over the local LAN, Litter can treat those as two different servers. Once both are connected, thread/session state becomes inconsistent:

  • threads can appear twice
  • sending a message in one copy of a thread can update the duplicate copy instead of the one currently open

Steps to reproduce

  1. Have one machine reachable from the phone both:
    • by local LAN IP, and
    • by Tailscale IP / MagicDNS
  2. Discover/connect to that same machine through both paths so Litter ends up with 2 connections to one physical server.
  3. Open the sessions/thread list.
  4. Send a message in one of the duplicated threads.

Actual result

  • The same server effectively exists twice.
  • Threads can be duplicated.
  • Message updates can appear under the duplicate server/thread entry instead of the thread instance that was used to send the message.

Expected result

The same physical remote machine should collapse to one canonical server identity, even if it is discovered or connected through multiple network paths. Threads should appear once and message updates should always land in the currently selected thread.

Suspected cause

From code inspection, discovery/session identity is address-based:

  • discovered server IDs are created from host/address, e.g. network-<host>
  • discovery reconciliation dedupes by normalized host only
  • thread state is keyed by (server_id, thread_id)
  • active sessions are reused only by server_id

That means one machine on two addresses gets two different server_ids, and then the store treats the same upstream threads as separate thread keys.

Relevant code:

  • shared/rust-bridge/codex-mobile-client/src/discovery.rs
  • shared/rust-bridge/codex-mobile-client/src/types/models.rs
  • shared/rust-bridge/codex-mobile-client/src/store/reducer.rs
  • shared/rust-bridge/codex-mobile-client/src/mobile_client_impl.rs

Suggested fix direction

Use a canonical remote-server identity that survives multiple network paths, instead of keying everything off the currently used host/IP. If the app-server protocol does not expose such an identity yet, it may need to be added during initialize/handshake and then used to collapse aliases before storing sessions/threads.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions