[Bug]: Agent link card can't be declined or dismissed from a client that can't manage access#26952

opened4d agobyPPseudogiant-xr

Before submitting

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

Area

apps/web (apps/mobile has the same gate)

Summary

When an agent asks to link a machine (t3_environment_link), a client whose session cannot manage access sees the card with no buttons at all, only "Only a session that manages access here can answer this." The card cannot be declined or dismissed from that client, so it stays pending in the thread until the thread is stopped or archived.

Steps to reproduce

  1. Connect a client to a T3 server with a session that lacks the permission behind peerLinkEnvironment.answerRequest (here: a desktop client viewing a thread on a remote Linux server, not as that server's access administrator).
  2. In a thread on that server, ask the agent to open work on another, not-yet-linked machine, so it calls t3_environment_link with a hint.
  3. Look at the link card.

Expected behavior

Any client that can see the card can at least decline it, or the card says how to clear it (for example, "Stop or archive the thread to cancel this request"). Linking itself can stay restricted to sessions that manage access.

Actual behavior

The card shows the title and reason, then only "Only a session that manages access here can answer this." No Decline button. Nothing else in the thread closes it, so the thread keeps showing pending input.

In apps/web/src/components/chat/LinkRequestCard.tsx (main @ 6d450a4284, around lines 95–152), Decline and "Choose machine…" share one gate:

tsx
1const canAnswer = useAtomValue(
2 peerLinkEnvironment.answerRequest.permissionAtom(props.environmentId),
3);
4...
5{canAnswer ? ( /* Decline + Choose machine… */ ) : (
6 <p>Only a session that manages access here can answer this.</p>
7)}

apps/mobile/src/features/threads/LinkRequestCard.tsx (lines 114–182) does the same.

Declining links nothing and grants nothing, so it probably doesn't need the same permission as accepting. If the server's answer RPC also requires it for a decline, the server side would need the same split.

Impact

Minor bug or occasional failure

Version or commit

0.1.4-nightly.20261029.3853 (server, linux-x64)

Environment

Server: Linux x64, T3 Code 0.1.4-nightly.20261029.3853. Client: T3 Code desktop app viewing a thread on that remote server. Agent: Claude Code (Claude Opus 5.5).

Logs or stack traces

None. The behavior follows from the gate above.

Workaround

Stop or archive the thread. Per #17129, either closes a pending link card as cancelled. Or open the thread from a client that manages access on that server.

Related, but not the same: #26944 (closes obsolete link cards after a matching retry succeeds; nothing was linked here) and #17129 (the feature).