{"record":{"id":"3f60af9a95ca28d0","repo":"block/buzz","slug":"could-not-authorize-a-mentioned-agent-check-its-a","errorCode":null,"errorMessage":"Could not authorize a mentioned agent. Check its access and channel membership, then retry or remove the mention.","messagePattern":"Could not authorize a mentioned agent\\. Check its access and channel membership, then retry or remove the mention\\.","errorType":"exception","errorClass":"AgentMentionAuthorizationError","httpStatus":null,"severity":"error","filePath":"desktop/src/features/messages/lib/agentMentionRevalidation.ts","lineNumber":93,"sourceCode":"  });\n  const admittedPubkeys = new Set(\n    [...agentPubkeys].filter((pubkey) => {\n      const isManagedAgent = managedPubkeys.has(normalizePubkey(pubkey));\n      const directoryReady = isManagedAgent || relayDirectoryReady;\n      return (\n        getAgentMentionAdmission({\n          isAgent: true,\n          pubkey,\n          mentionableAgentPubkeys: mentionablePubkeys,\n          directoryReady,\n        }) === \"allow\"\n      );\n    }),\n  );\n  if (\n    [...requestedAgentPubkeys].some((pubkey) => !admittedPubkeys.has(pubkey))\n  ) {\n    throw new AgentMentionAuthorizationError();\n  }\n  return [...pubkeys];\n}\n\nexport function useAgentMentionRevalidation({\n  agentPubkeys,\n  getSelectedAgentPubkeys,\n  currentPubkey,\n  eligibilityScope,\n  sharedChannelIds,\n  refetchManagedAgents,\n}: {\n  agentPubkeys: ReadonlySet<string>;\n  getSelectedAgentPubkeys: () => ReadonlySet<string>;\n  currentPubkey: string | null;\n  eligibilityScope: AgentEligibilityScope;\n  sharedChannelIds: ReadonlySet<string>;\n  refetchManagedAgents: () => Promise<DirectoryResult<ManagedAgent[]>>;","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/block/buzz/blob/dad5a33865fc81a2e55b3b60746632f615ec1e3a/desktop/src/features/messages/lib/agentMentionRevalidation.ts#L75-L111","documentation":"revalidateAgentMentionPubkeys re-checks, at send time, that every mentioned agent pubkey is admitted (access policy + channel membership). If any requested agent pubkey is missing from the admitted set, it throws AgentMentionAuthorizationError so the send fails closed instead of mentioning an agent that cannot or should not respond.","triggerScenarios":"Sending/editing a message whose @agent mention fails send-time revalidation: the agent's respond_to policy no longer admits the viewer, the agent is not a member of the destination channel, or the directory/membership query returned no evidence for the pubkey.","commonSituations":"Agent was removed from the channel after the mention was typed; shared agent's allowlist/anyone policy changed; relay membership or directory cache is stale; editing an old message that still mentions a since-removed agent.","solutions":["Open the mention picker and re-select the agent — this refreshes eligibility and membership before send.","Add the agent back to the destination channel (Invite) or have its owner update the respond_to policy to admit you, then retry.","Remove the mention from the message and send without it.","If eligibility looks wrong, refresh the relay directory/membership caches and retry the send."],"exampleFix":"// before\nawait sendMessage({ content, mentions: extracted.pubkeys });\n\n// after\ntry {\n  await sendMessage({ content, mentions: extracted.pubkeys });\n} catch (e) {\n  if (e instanceof AgentMentionAuthorizationError) {\n    toast.error(\"A mentioned agent is not authorized here. Re-pick the mention or remove it.\");\n    return; // keep the draft\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"const admitted = await revalidateAgentMentionPubkeys({ pubkeys, channelId }); // pre-check before submit\nif (admitted.length < pubkeys.length) promptMentionPicker();","typeGuard":"function isAgentMentionAuthError(e: unknown): e is AgentMentionAuthorizationError {\n  return e instanceof AgentMentionAuthorizationError;\n}","tryCatchPattern":"try {\n  await send();\n} catch (e) {\n  if (isAgentMentionAuthError(e)) {\n    toast.error(\"A mentioned agent lost access to this channel. Re-pick or remove the mention.\");\n    return; // preserve draft\n  }\n  throw e;\n}","preventionTips":["Always insert agent mentions through the picker so eligibility is checked at selection time.","Re-run revalidation after any channel-membership or policy change before send.","Never strip denied mentions silently — surface the denial and keep the draft.","Keep directory/membership caches invalidated on agents-data-changed events."],"tags":["mentions","authorization","agents","fail-closed"],"backgroundTag":"agent-mention-authorization-denied","analyzedSha":"dad5a33865fc81a2e55b3b60746632f615ec1e3a","analyzedAt":"2026-09-05T18:13:50.666Z","contentChangedAt":"2026-09-05T18:13:50.666Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}