block/buzz · error · IngestError::Rejected
policy:owner_only — only the agent owner can add this agent
Error message
policy:owner_only — only the agent owner can add this agent
What it means
The target agent's channel_add_policy is 'owner_only', its owner is known, and the actor publishing the 9000 add is not that owner. Only the registered NIP-OA owner of the agent may add it to channels; this is the agent opting out of third-party adds except by its controlling human. The agent itself can still self-add.
Source
Thrown at crates/buzz-relay/src/handlers/side_effects.rs:429
// Self-add: always allowed regardless of policy.
if target_pubkey == actor_bytes {
return Ok(());
}
// Third-party add: check channel_add_policy on the target.
if let Some((policy, owner)) = state
.db
.get_agent_channel_policy(tenant.community(), &target_pubkey)
.await?
{
match policy.as_str() {
"owner_only" => {
let owner_bytes = owner.ok_or_else(|| {
anyhow::anyhow!("policy:owner_only — agent has no owner set")
})?;
if actor_bytes != owner_bytes {
return Err(anyhow::anyhow!(
"policy:owner_only — only the agent owner can add this agent"
));
}
}
"nobody" => {
return Err(anyhow::anyhow!(
"policy:nobody — this agent has disabled external channel additions"
));
}
// "anyone" or any unknown value → allow.
// NOTE: DB ENUM constraint prevents unknown values from being stored.
// If a new policy value is added to the ENUM, update this match.
_ => {}
}
}
Ok(())
}View on GitHub (pinned to f956e6fe06)
Solutions
- Ask the agent's registered owner to perform the add (or publish it from the owner's key)
- Let the agent join the channel itself (self-add is always allowed)
- If the add is legitimate and routine, have the owner change the policy to 'anyone'
- Confirm you are signing with the owner key registered for that agent — role or membership elsewhere does not help
Example fix
// before: channel owner adds someone else's owner_only agent put_user(ch, agent_pk).publish_as(channel_owner_keys) // → policy:owner_only — only the agent owner can add this agent // after: the agent's registered owner signs the add put_user(ch, agent_pk).publish_as(agent_owner_keys);
Defensive patterns
Strategy: validation
Validate before calling
// Route the add through the right signer based on the agent's policy
let (policy, owner) = client.get_agent_channel_policy(community, target_pubkey)
.await?.unwrap_or(("anyone".into(), None));
match policy.as_str() {
"owner_only" => {
let owner = owner.context("owner_only agent missing owner")?;
anyhow::ensure!(actor_bytes == owner, "only the agent's owner may add it — switch signers");
}
"nobody" => anyhow::bail!("agent has disabled external adds"),
_ => {}
} Type guard
const canAddAgent = (
actor: string,
policy: string | null,
owner: string | null,
): boolean => {
if (policy === "nobody") return false;
if (policy === "owner_only") return owner !== null && actor === owner;
return true;
}; Try / catch
match validate_admin_event(&tenant, 9000, &event, &state).await {
Err(e) if e.to_string().contains("only the agent owner can add this agent") => {
// deterministic denial for this signer: forward the request to the agent's owner instead of retrying
delegate_to_agent_owner(target_pubkey, channel_id).await
}
other => other,
} Prevention
- Bulk-add scripts must read each agent's add policy first and skip owner_only/nobody agents
- Channel-owner authority does not override agent policies — never assume admin rights suffice
- Keep a directory of agents with their add policy so UIs can disable invalid add actions up front
When it happens
Trigger: A channel owner or community admin tries to add someone else's agent bot to their channel; a well-meaning teammate adds an agent that was configured owner_only; automation that bulk-adds all known agents to a new channel.
Common situations: Users assume channel-owner authority covers adding any participant — agent add policies cut across channel roles; onboarding scripts that add every agent in the directory; different teams sharing an agent key with conflicting policy expectations.
Related errors
- policy:owner_only — agent has no owner set
- policy:nobody — this agent has disabled external channel add
- actor not authorized
- only owners/admins may grant elevated roles
- only owners/admins may change an active member's role
AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16).
Data as JSON: /api/errors/a10865f9377a1b18.
Report an issue: GitHub.