block/buzz · error · IngestError::Rejected
policy:nobody — this agent has disabled external channel add
Error message
policy:nobody — this agent has disabled external channel additions
What it means
The target agent's channel_add_policy is 'nobody': the agent has disabled all external channel additions. The relay rejects the 9000 add regardless of who signs it — only the agent's own self-add path (target == actor) goes through, since that returns Ok before the policy match. The DB ENUM constraint means only owner_only/nobody/anyone can be stored, so this is a deliberate opt-out, not an unknown value.
Source
Thrown at crates/buzz-relay/src/handlers/side_effects.rs:435
// 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(())
}
9001 => {
// REMOVE_USER: self-remove allowed unless actor is the last owner; removing others requires owner/admin
let target_pubkey =
extract_p_tag(event).ok_or_else(|| anyhow::anyhow!("missing p tag"))?;
if target_pubkey == actor_bytes {
// Self-removal: must be an active member, and cannot be the last owner.View on GitHub (pinned to f956e6fe06)
Solutions
- Have the agent join the channel itself (self-add) if membership is desired
- If external adds should be allowed again, the agent/operator changes the policy away from 'nobody'
- Remove the agent from bulk-add lists when its policy is nobody, and surface policy state in admin tooling
Example fix
// before put_user(ch, agent_pk).publish_as(anyone_keys) // → policy:nobody — this agent has disabled external channel additions // after: agent self-adds put_user(ch, agent_own_pk).publish_as(agent_keys); // target == actor → allowed
Defensive patterns
Strategy: validation
Validate before calling
// Respect the opt-out before publishing
let policy = client.get_agent_channel_policy(community, target_pubkey).await?;
anyhow::ensure!(
policy.as_deref() != Some("nobody"),
"agent has disabled external channel additions — ask it to self-join"
); Type guard
const blocksExternalAdds = (policy: string | null): boolean => policy === "nobody";
Try / catch
match validate_admin_event(&tenant, 9000, &event, &state).await {
Err(e) if e.to_string().contains("policy:nobody") => {
// hard opt-out: no signer can pass; trigger the agent's own join flow instead
invite_agent_self_join(target_pubkey, channel_id).await
}
other => other,
} Prevention
- Treat policy:nobody as a permanent 403 for external adds — do not build retry logic around it
- Ask agents to self-join (self-add bypasses policy) via your normal agent-automation channel
- Keep agent directories in sync with policy state so retired/locked agents drop out of add lists
When it happens
Trigger: Any third-party 9000 naming an agent whose policy row is 'nobody'; bulk onboarding flows that sweep agent pubkeys into channels; attempting to add a retired or sandboxed agent that was locked down.
Common situations: Agents configured for single-channel use whose operators set nobody after setup; post-incident lockdown of an agent that was being spammed into channels; shared directories still listing agents that have since opted out.
Related errors
- policy:owner_only — agent has no owner set
- policy:owner_only — only the agent owner can add this agent
- missing or invalid h tag
- channel not found
- channel is archived
AI-assisted analysis of block/buzz@f956e6fe06 (2026-08-16).
Data as JSON: /api/errors/39af39db506ca877.
Report an issue: GitHub.