Repository navigation
Description
Describe the bug
When the same user installs Buzz Desktop on a second machine and joins the same community, the second install creates its own set of default agents with fresh Nostr keypairs and adds them all to the shared channel. The agents carry identical display names to the ones already there, so the channel roster shows each agent multiple times.
Our Welcome channel shows 8 members for what is really 1 human + 3 agents.
Single self-hosted community, fresh install — so this is not the cross-community collision in #2515.
To Reproduce:
- Install Buzz Desktop on machine A, join a community, let the default agents (Fizz, Honey, Bumble) be created, and add them to a channel.
- Install Buzz Desktop on machine B and sign in to the same community as the same user.
- Open the same channel and run
buzz channels members --channel <uuid>.
Expected behavior:
An agent should have one identity and one channel membership per community, regardless of how many machines the owner installs on. A second install should register as an additional runtime for the existing agents rather than minting parallel same-named identities.
Supporting Material
Channel roster — buzz channels members, each pubkey resolved with buzz users get:
| Display name | Pubkey (first 8) | Role | Has ever posted |
|---|---|---|---|
| Serge | bab2c2c9 |
owner | yes |
| Fizz | c9afa13c |
member | yes |
| Fizz | 614f28ba |
bot | yes |
| Fizz | 4ecf356f |
bot | yes |
| Honey | c6cd9fae |
bot | yes |
| Honey | c4125e50 |
bot | no |
| Bumble | 8f0a2aa1 |
bot | yes |
| Bumble | 90401f8c |
bot | no |
Six bot identities = 2 installs x 3 default agents. The seventh agent identity is an extra Fizz carrying role member rather than bot, which suggests a second creation path that disagrees on the role to assign.
Message counts with first/last post per pubkey, aggregated across all channels:
c9afa13c n=11 22:04:20 - 22:40:19 Fizz (role: member)
bab2c2c9 n=32 22:08:11 - 23:28:45 Serge (human)
614f28ba n= 7 22:52:44 - 23:18:30 Fizz \
c6cd9fae n= 1 23:12:28 Honey > install A
8f0a2aa1 n= 1 23:12:33 Bumble /
4ecf356f n= 5 23:19:50 - 23:27:07 Fizz \
c4125e50 n= 0 never posted Honey > install B
90401f8c n= 0 never posted Bumble /
Install B's first activity is at 23:19:50, ten seconds after the user first posted from the second machine. Install B's Honey and Bumble have never posted — they were never invoked on that machine. They exist purely because the install registered them.
That detail is what pins the cause to install time rather than session start: identities are created for agents that are never run.
Environment
- OS: macOS
- Buzz Desktop 0.4.23
- Self-hosted relay, single community, same user account on both machines
Additional context
We may simply be holding this wrong — if creating per-machine agent identities is the intended design, we would appreciate knowing what the supported way to use one agent from two machines is.
Impact as we experience it:
- Member count inflates by the whole default roster per machine.
@mentiontargets are ambiguous — several live pubkeys share the nameFizz, and which one a mention reaches is not predictable.- Most duplicates are dead on arrival. An identity minted on machine B holds its key in machine B's keyring only, so it sits in the roster looking available while nothing can run it from elsewhere.
- Roles are inconsistent across creation paths (
membervsbot).
This appears consistent with the key-ownership model described in #2349, where a second machine "does not possess the agent's private key by design" — install B therefore has no way to adopt the existing agents and creates its own.
Possibly related, though none report roster duplication itself:
- [Bug] Remote managed agents are hidden and unmentionable on secondary devices #2349 — remote managed agents hidden/unmentionable on secondary devices (visibility half of the same multi-machine area)
- [Bug] Remote Agent Missing from @ Mention Autocomplete Across Machines #2508 — remote agent missing from
@mention autocomplete across machines - [Bug] Renaming or re-adding personal agents can desynchronise identity and break @mentions #2423 — renaming/re-adding agents desynchronises identity (same symptom class, rename trigger)
- Additional Running Agents after restart #2157 — additional running agents after restart (possibly the same underlying issue)
- [Bug] Agents from different communities collide in channels, causing duplicate @mention targets and missing avatars #2515 — cross-community agent collision (same symptom, different axis; ruled out here)
Suggested directions:
- Do not auto-create the default agent roster on an install that joins a community where those agents already exist.
- Separate agent identity from agent runtime, so a new machine registers as another runtime for an existing identity.
- Reconcile role assignment across creation paths.
- Offer a way to prune duplicate memberships so affected channels can be cleaned up.
- Disambiguate same-named identities in the mention picker while duplicates can exist.
Activity
chessing234 commentedon Jul 24, 2026
Partial fix in the open PR — second install no longer adds same-named Welcome Team bots into the channel roster.
matthewdcage commentedon Jul 29, 2026
Additional data point — duplicate mint on single install (#3639)
We filed #3639 for a separate mint path that produces the same roster inflation as this report without a second machine.
Upstream root cause (
block/buzzmain)desktop/src/features/agents/ui/AddTeamToChannelDialog.tsx(~line 152) passesforceNewInstance: truefor every persona on Deploy team to channel. That bypasses reuse inprovisionChannelManagedAgent()/findReusablePersonaAgent()(channelAgents.ts). Tauricreate_managed_agentalways mints new keys — frontend reuse is the only guard, and team deploy disables it.Reproduction we verified (single Desktop, single community)
Buzz Desktop 0.5.1, one install, hosted community (not self-hosted fork):
buzz channels members --channel <id>shows new bot pubkeys with the same display names.We counted ~24 distinct bot pubkeys across channels vs 12 running managed instances before cleanup. Example duplicate groups: Fizz (×4), SEO Agent (×4). This matches the
@mentionambiguity and dead-roster symptoms described here, but the trigger was repeated team deploy, not a second install.Relationship to this issue
The contributor note about a partial PR for second-install Welcome Team bots addresses a different entry point; #3639 covers the explicit
forceNewInstance: truepath still onmain.We are preparing a PR removing that flag plus in-channel persona dedup. Happy to cross-link PRs when open.
christophcemper commentedon Jul 31, 2026
We experience this in similar ways
Summary
Buzz Desktop creates a new keypair for each agent on each machine. When the same logical agent (e.g. "Fizz") is set up on multiple machines, the relay and channel rosters accumulate multiple distinct identities with the same display name. There is no mechanism to sync, merge, or deduplicate these identities across devices.
Observed behavior (Welcome channel, 2026-07-31)
Total bot members: 13 (should be 5)
Impact
205e61b5…still holds owner role on #project-management.Root cause (hypothesis)
Buzz Desktop agent creation mints a fresh Nostr keypair per machine. Creating the same-named agent on a second machine does not reuse or import the first machine's key — it produces a new identity that joins the same channels as a separate member. The relay has no concept of "same logical agent across devices."
Related GitHub issues
No existing GitHub issue found
Searched block/buzz issues for: duplicate agents, per-machine keypair, multiple identities, stale roster members, duplicate keys. No matching open issue found — this appears to be unreported upstream.
Proposed fix (for upstream)
Immediate workaround
buzz agents archive.buzz channels remove-member.AI-OWEN commentedon Jul 31, 2026
Another data point, and a variant trigger: Desktop 0.5.3 (newer than the 0.5.2 confirmed above — still reproduces).
Setup
buzz-acpunder systemd. These are the intended canonical identities.Roster
Six identities for three logical agents — but not distributed one-per-agent. Display names resolved with
buzz users get --pubkey <hex>on each of the six:85f63083,775423a7,5ea798862127b943,6cfb857809aa16bfThe lopsided 3 / 2 / 1 shape is worth flagging, because it is not what a clean
one-mint-per-machine model predicts — that would give a symmetric 2 / 2 / 2. It is
what you would expect if hosting is re-established repeatedly and reuse succeeds
only sometimes, which matches the process evidence in the next section.
Two independent signals separate the canonical identities from the strays, and they
do not fully agree:
85f63083http://192.168.200.100:3000(LAN)2127b943http://192.168.200.100:3000(LAN)09aa16bfhttps://<relay>.ts.net(tailnet)775423a7https://<relay>.ts.net5ea79886https://<relay>.ts.net6cfb8578https://<relay>.ts.netPresence splits 3 / 3. Avatar host splits 2 / 4 — the image hashes are identical
across the pairs, only the base URL differs, so the host is a fingerprint of which
install uploaded the avatar. Honey sits on the stray side by that fingerprint while
being persistently online and having no twin at all. I don't have an explanation for
Honey yet and am not claiming one.
Variant worth noting: hosting is re-established on plain app launch
Neither of the two triggers in this thread applies here — no second Desktop install, and no "Deploy team to channel". The Mac had already been through setup. Simply having Buzz Desktop running re-establishes a full local host stack.
Process evidence from a single Desktop session (
pswith start times):Three separate host stacks spawned at three different times, accumulating over ~10 minutes within one launch — 34 processes total. Earlier in the same session it was 23 (1 desktop + 2
buzz-acp+ 20claude-agent-acp).User-facing cost: duplicates silently swallow messages
Adding this because the thread so far treats duplicates as roster clutter. Measured
on this deployment, they are worse than that: they make mentions a coin flip that
fails silently.
With two
Bumbleidentities in the channel — one live on the VM, one dark — theiOS client's
@picker offered both, with nothing in the row to tell them apart.Four consecutive mentions by the channel owner, from the same device, in the same
thread:
ptag2127b943(live)6cfb8578(dark)6cfb8578(dark)2127b943(live)Half the messages went to a key with no running harness. There is no error, no
delivery warning, and no visual difference between the two picker entries — from the
user's side it is indistinguishable from the agent ignoring them, and the observed
behaviour was to re-send the message and assume the agent was broken.
Note this is a different failure from #3277. Here the
ptag ships correctly andthe picker does list the agent; the tag simply names the wrong same-named identity.
A fix for mention eligibility would not address it. Deduplication, or at minimum
disambiguating same-named identities in the picker, would.
The CLI has the same gap from the other direction: sending with an
@Namethatmatches multiple channel members resolved silently to one of them (the dark one)
rather than reporting the ambiguity — observed once, in a signed event whose
ptagnames
6cfb8578. This build ofbuzz messages sendexposes no flag to specify theintended pubkey, so there is no way to disambiguate by hand.
The gap underneath this
There is no way to run Desktop as a client only. If your agents live on another machine, opening Desktop to read a channel re-establishes local hosting. Duplicate identities aren't really a mint-path bug from this angle — they're the unavoidable consequence of a client that always hosts. Cross-referencing #3554, which asks for exactly this shape.
Edited 2026-08-01: the original version of this comment presented the roster as
"one keeper + one stray per agent" and mapped
5ea79886to Bumble and6cfb8578to Honey. Both were wrong —
5ea79886is a third Fizz and6cfb8578is thesecond Bumble, per
buzz users get. The true distribution is 3 / 2 / 1.Corrected above, and added the presence/avatar breakdown and the message-loss
measurement.
christophcemper commentedon Aug 5, 2026
@wesbillman Wes I believe this defect is a show-stopper for multi-user, or even multi-device use
wesbillman commentedon Aug 5, 2026
From my agents...
Shipitrealgood commentedon Aug 5, 2026
@wesbillman or Wes's agent.
On this -
This is a hangover behavior from #2149 merge. Sharing in case this context helps that this is a gating issue introduced there, unintentionally, and many small pr's exist to solve this without reintroducing the issue it was designed to stop. Ex. #3676.
This or one of the many could be adopted interim potentially to alleviate pressure while #4593 is formalized and pushed out?
drainodrew commentedon Aug 8, 2026
Fresh production evidence: iOS New message shows three Bumble pubkeys
We reproduced the user-facing failure on 2026-08-08. The iOS New message sheet returns three rows named Bumble:
1c992caf3d5f21aa7dd7cf96a8db28a0a568e2c1089da13b4ecb9c09ea5165e13dc09be47832ad45d08ae23ec1934daa99ab175dad065c70aa7487555f91cf546546126a64bf7f734b671b3503023915c36c278003036784a7c0101852d0f1ebbuzz users get --name Bumbleresolves all three as separate kind:0 profiles with the same display name/avatar. Activity differs:1c992caf…has historical posts,3dc09be4…is the currently responding identity, and a scopedbuzz messages search --author 6546126a… --limit 20returned no messages.The phone is exposing the duplicates, not minting them
On current
maininspected atf029deafae6ad3b63e13c29104f3be76122cb1df, mobile New DM discovery in:mobile/lib/features/channels/channel_management_provider.dartmobile/lib/features/channels/channels_page/sheets.dartqueries kind:0 profiles and deduplicates only by pubkey. It has no managed-agent key creation path. Desktop
create_managed_agent, however, still reachesKeys::generate()without a backend one-persona/one-key invariant.This means the evidence does not establish “one identity per MacBook, Mac mini, and iPhone.” It establishes three real pubkeys, two with observed activity states and one inert in the scoped search. Device attribution requires each Desktop's local key/runtime records.
Current implementation gap
The maintainer direction in this thread is right: NIP-PMA identity portability (#4593, #5133, current Desktop work in #4999) plus runtime lease/fencing. A warning alone (#3912) does not prevent two hosts from replying.
There is also a narrower mobile gap visible in this screenshot: #3887 filters archived identities from mention autocomplete, but New DM uses separate directory providers. After a human archives a stale identity, it can still remain discoverable in this sheet unless the archived snapshot is applied to
relayDirectoryUsersProviderandrelayDirectorySearchProvidertoo.Suggested focused follow-up:
We can provide the original iOS screenshot and help run an isolated two-Mac verification matrix for #4999.
drainodrew commentedon Aug 8, 2026
The focused mobile discovery fix is now available as draft PR #5359:
#5359
It rebases and extends #3887 so archived identities are filtered from New DM browse/search as well as mention autocomplete. The full repository
just cigate passed at commit83289dde8089b16d5890a45b8e840fd23d6de13c, including all 1,267 Flutter tests.This is deliberately the UI/discovery cleanup slice; identity portability and single-runtime fencing remain separate work.
jcg-git commentedon Aug 12, 2026
Confirmed reproducible on
desktop-v0.5.10(currentmainas of 2026-08-12), and found the root cause in the dedup path — sharing in case it's useful, plus a workaround.Reproduction: isolated relay (own Postgres/Redis, zero shared state with any real deployment), one machine joins first and creates the built-in Welcome Team normally (1 owner + 3 bots). A second machine, signed in as the same owner identity, joins the same community fresh — Welcome channel jumps to 1 owner + 6 bots. Two independent test passes, same result both times.
Root cause, traced in
desktop/src/features/onboarding/welcomeGuide.ts,provisionWelcomeTeam():The dedup check exists and is reasonable — it's just checking the wrong scope.
listManagedAgents()calls the Taurilist_managed_agentscommand, which reads that machine's own localmanaged-agents.jsononly. There's a separatelistRelayAgents()that queries the community/relay directly, butprovisionWelcomeTeamdoesn't use it here. So a second machine's local file is empty, the lookup finds no match even though the identities already exist on the relay, and it mints new ones.Matches the "expected behavior" already stated in the issue — a relay-aware lookup (or the
listRelayAgents()path already in the codebase) in this dedup check would fix it at the root. I know #5359 covers the discovery/filtering slice (hiding archived identities from pickers) — this is a different, earlier point in the flow: preventing the duplicate identities from being minted in the first place, not just hiding them afterward. Happy to be pointed at existing tracked work if this overlaps something already planned.Workaround, confirmed working via a clean A/B test: before a new machine's first launch (before it ever opens Buzz Desktop / joins the community), pre-seed its local
managed-agents.jsonwith the existing three Welcome Team records — samepubkey,persona_id,team_id: builtin-team:welcome, andrelay_urlas already exist on the reference machine. With that in place,pickWelcomeTeamStarterAgentForRelayfinds a match andcreateManagedAgentis never reached. Tested twice on the same second machine: without the pre-seed, duplicates were created; after resetting local state and pre-seeding, rejoining the same community produced zero new duplicates.Caveats: this only prevents new duplicates going forward — it doesn't retroactively clean up ones already created, and it requires the operator to have access to the existing records (i.e. isn't something an end user could easily do without a bit of scripting). Not a substitute for the real fix, just something that unblocked us in the meantime.
For anyone who already has duplicates and wants to clean them up:
buzz agents archive <pubkey>alone is not enough — it flags the identity as archived but does not remove it from channel membership (confirmed: member count was unchanged after archiving until a separate call). You need both:Both are owner-signed relay actions, so — unlike the agent records themselves — the removal is immediately visible from any device querying that channel, no per-machine sync issue there. Worth calling out since the Desktop UI's delete action presumably bundles both steps together, but the CLI keeps them separate and it's easy to assume archiving alone did the job.
ciscosurplus commentedon Aug 18, 2026
Adding a second-owner-two-Mac data point on desktop-v0.5.14, hosted relay, single community — plus a few mechanics that may help whoever picks up the repair side.
Setup: Mac A (work) hosts the original Fizz/Honey/Bumble plus five custom agents. Mac B (personal) signed in as the same owner on 15 Aug.
What we observed
malformed BUZZ_ACP_SETUP_PAYLOAD: unknown variant missing_binary, exit 1, ~340-byte log each launch). Same shape as Secondary Desktop on the same identity auto-seeds/hosts the builtin Welcome Team, creating duplicate ghost agents that hijack @mentions #6211.managed-agents.jsonrecords for a shared persona carry the samepersona_source_versionon both machines, and a Desktop save of the persona on Mac A wrote the persona record at 17:27:59Z, the instance record at 17:31:09Z, and relaunched the agent at 17:31:40Z. So an edit is visible in the persona ~3 minutes before it reaches the body — matches the ~7-minute cross-machine propagation in RFC RFC: One identity, many bodies. Body registry, event leasing, and ghost-key repair #5667.buzz channels remove-memberis owner-only and worked, but Desktop still p-tags the removed key when the owner types@Name(opened separately as Desktop resolves typed @Name against all known profiles, not channel members — a removed duplicate identity still gets p-tagged, so remove-member cannot repair a mention collision #6247). Renaming the ghost's display name was the only remedy that fixed mentions.Happy to supply the anonymised
managed-agents.jsonrecords and agent logs if useful.Eugene3dotdev commentedon Nov 1, 2026
Still reproducible on
desktop-v0.5.28(commitf87c1089), self-hosted relay, one community, same owner identity on two Macs. Adding the exact guards that let it through at this version, since the earlier traces predate thev2storage key.Second machine, first launch. Onboarding is skipped because the owner's kind:0 exists (
desktop/src/features/onboarding/hooks.tsL372-384,hasExistingProfile). Welcome Team seeding then runs because its "already ensured" marker islocalStorageon that machine only (welcome.tsL293-309, keybuzz-welcome-channel-ensured.v2:<pubkey>:<community>),provisionWelcomeTeam()consults only the locallistManagedAgents()(welcomeGuide.tsL306-370), finds nothing, and mints Honey/Fizz/Pollen with fresh keys. Result on our relay:buzz users get --name Honeyreturns three pubkeys, Fizz three, Pollen three; machine A'smanaged-agents.jsonholds none of them.Same root, different trigger. Creating a channel from a template that carries a team (
desktop/src/features/agents/channelAgents.tsL296, L397) minted a second instance of three custom agents on machine A itself (records.iter().any(|r| r.pubkey == pubkey)incommands/agents.rsL461 can only ever dedupe against a just-generated key). Those three rows have one channel, zerosession/newin their logs, and are restarted on every app launch.Why inbound sync cannot repair it. The relay carries a secretless kind:30177 head per instance, and the desktop never materializes a head into a local record by design (
event_sync.rsL684-691,commands/personas/inbound.rsL736-749). So the second machine has no way to learn "this persona already has a live instance elsewhere" before minting.Smallest fix I can see: make the seeding and template guards consult relay state (kind:30177 heads, or kind:0 profiles under the owner's auth) in addition to
localStorage/local records, and skip minting when a non-archived instance of the same persona already exists. Cleanup on our side isbuzz agents archiveper duplicate; there is no desktop-side import, so the extra keys cannot be adopted.