Skip to content

A line to a friend's Bot that is gone fails with a raw, doubled reason and an unusable Retry #954

Closed

Description

@Birfy

From the product self-test routine (real web UI, two isolated homes on main ed60c5a1).

Steps

  1. Home A shares its Bot with home B; B talks to it in the normal chat window and leaves that chat open.
  2. That Bot stops existing for B (on A's side it is removed / no longer listed).
  3. B types one more line and presses Enter.

Expected

One sentence in the failed card that names the Bot and says what to do next - the same conversation already prints exactly that sentence (<Bot> (@handle) is no longer shared with you, so messages to it cannot be delivered. … Ask its owner for a new invite.). Retry should be absent or disabled, because the Bot does not exist any more and Retry can only fail again.

Actual

The card says, twice in a row:

Not sent: no such remote bot. Try again. Try again.
  • no such remote bot is the Bot Social server's wording passed through unchanged: it names nothing, and a person cannot act on it.
  • Try again. appears twice.
  • A Retry button is offered on a failure that can never succeed; pressing it repeats the same card.
  • The friendly sentence quoted under Expected is printed separately in the same conversation, so the screen says both "no such remote bot" and "ask its owner for a new invite" about the same event.

Where it is

  • Failure text comes from the Bot Social error in plugins/social/src/social.js (the send path around the bot_not_shared / missing-remote handling, ~:1485-1510) and is pushed into the chat as a failed item.
  • Card: plugins/social/client.js:1933 (ChatApproval, data-state: 'failed') renders item.error verbatim and always adds the Retry button (data-flybot=hold-retry).
  • The good sentence lives in core/src/client/model-menu.js:246.

Evidence

Two homes (.dsh-test-a / .dsh-test-b), real Chromium, reports/ui-journey/sr3-02-b-sent-after-revoke.txt and reports/ui-journey/sr3-03-b-after-reload.txt in the self-test workspace. The same run confirmed the good sentence renders in the same pane, so both strings are one event.

Scope

Copy plus one decision (Retry or not) - plugins/social/client.js and the error the send path records; no protocol change.

Not filed before: searched no such remote bot, no longer shared and Not sent - no open or closed issue matches.

Activity

  1. added
    bugSomething isn't working
    area:socialFriends, invites, grants, Bot Social
    area:uiWeb/desktop UI and copy
    self-testFiled by the product self-test routine (issues only)
    on Oct 24, 2026
  2. Birfy commented on Oct 24, 2026

    @Birfy
    CollaboratorAuthor

    Triage (deduped against #428, #413, #886, #881: all closed, none covers the terminal phrase or the doubled step).

    What the person sees

    Not sent: no such remote bot. Try again. Try again.
    [Retry]
    

    and one line below, the chat dock for the same Bot reads … is no longer shared with you … Ask its owner for a new invite. (core/src/client/i18n.js:284, drawn by RemoteGoneDock in core/src/client/model-menu.js:241-246, chosen at :199 when bot.remote.gone).

    Where it comes from — two independent layers

    1. plugins/social/src/social.js:1524 userFacingSendError() has branches for paused, not-shared, room-not-shared, no_relationship, grants, connection, 401/403/429, timeout — and nothing for "this handle is not on that home any more". The server's raw reason (no such remote bot / unknown remote bot) falls through to :1546-1551: short = (body || raw).slice(0, 100).replace(/\.$/, '') then return new Error(\${short}. Try again.`). So the phrase handed upward is no such remote bot. Try again.`.
    2. core/src/host/remote-chat.js:25 notSentLine() receives that sentence, matches none of its classifiers (:31-62), keeps it as short and appends its own step at :64: return \Not sent: ${short}. Try again.`. Hence Try again.` twice.

    The Retry is the failed-hold card: plugins/social/client.js:1929-1940 (item.status === 'failed') prints Not sent + item.error + the Retry button with data-flybot="hold-retry" at :1938. It calls onDecide(item, 'retry') for a failure that no retry can fix: only the owner sharing the Bot again helps, which is what the dock already says.

    Expected

    • A terminal reason (no such remote bot, unknown remote bot, Bot no longer published) becomes one human sentence, the same wording the dock uses: the Bot is no longer shared, ask its owner for a new invite. No internal phrase, no second Try again..
    • No Retry on that card: retrying cannot succeed. A retryable failure (429, timeout, paused) keeps its Retry and its single Try again..
    • Neither layer may append a step to a sentence that already ends with one: notSentLine() and userFacingSendError() must both check before adding Try again..

    Where to change

    • plugins/social/src/social.js:1524-1553 — add the terminal branch before the generic tail, and mark the error ({ retryable: false } or an existing flag) so the card can tell.
    • core/src/host/remote-chat.js:25-65 — classify the terminal reason, reuse the dock's sentence, and stop doubling the step.
    • plugins/social/client.js:1929-1940 — render Retry only when the item is retryable; otherwise no button.

    Acceptance

    1. Send to a Bot whose sharing was revoked → the notice is the dock's human sentence, exactly one step sentence, no token such as no such remote bot, send_as_member, or a raw lowercase reason id.
    2. That card has no Retry button (data-flybot="hold-retry" absent).
    3. Negative control: a 429 / timeout / paused failure still shows Retry and one Try again. — the fix must not remove the retry path globally.
    4. notSentLine() over an input that already ends with Try again. yields one step, not two (unit case in core/test/remote-chat.test.js).
    5. The change is mirrored in patches/ds-bot/files/ byte-identically for every touched core file (node scripts/ds-bot-patches.mjs check).

    Notes

  3. added
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 24, 2026
  4. self-assigned this
    on Oct 24, 2026
  5. added
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    on Oct 24, 2026
  6. Birfy commented on Oct 24, 2026

    @Birfy
    CollaboratorAuthor

    Written-by: Dev2

    Claiming this one. Branch 954-bot-gone-no-retry, cut from main d1052c0e; the fix and its tests are on the way as one PR.

  7. 2 remaining items

  8. removed
    agent-readyMaintainer-approved spec: an agent may take it. Only maintainers set this; never in a template
    on Oct 24, 2026
  9. removed
    agent-workingAn agent has claimed this issue (the claim comment names the branch)
    agent-prPull request opened by an agent
    on Oct 24, 2026
  10. Birfy commented on Oct 24, 2026

    @Birfy
    CollaboratorAuthor

    Checked this fix through the real UI on main 2ab9e3928279 (the merge that carried #961, before later merges) — the card path behaves as asked: after the owner revokes, the new card reads

    Chief (@chief.selftesta2.home) is no longer shared with you, so messages to it cannot be delivered. It runs on its owner's machine, so another model cannot stand in. Ask its owner for a new invite.

    one short message, no "Try again. Try again.", no Retry button in that card.

    One path is not covered: the inline failure line for the same situation still reads Not sent: peer has not granted chat.public. Try again. (internal capability name + a retry that can never succeed). Filed as #971 so this issue does not need to be reopened.

  11. added 2 commits that reference this issue on Oct 24, 2026
    311e3f6
    90f4bb5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:socialFriends, invites, grants, Bot Socialarea:uiWeb/desktop UI and copybugSomething isn't workingself-testFiled by the product self-test routine (issues only)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions