shareAI-lab/learn-claude-code · error · ValueError
Invalid mailbox recipient: {agent!r}
Error message
Invalid mailbox recipient: {agent!r} What it means
MessageBus._path() validates the recipient name against VALID_AGENT_NAME = ^[A-Za-z0-9_-]{1,64}$ before building the mailbox file path. Any recipient (or sender, since send validates both) outside that alphabet — spaces, dots, slashes, '@', unicode, empty, or longer than 64 chars — is rejected before the filesystem is touched, which simultaneously prevents path traversal via crafted names.
Source
Thrown at s13_agent_teams/code.py:792
MAILBOX_ROOT = MAILBOX_DIR.resolve()
VALID_AGENT_NAME = re.compile(r"^[A-Za-z0-9_-]{1,64}$")
RESERVED_TEAMMATE_NAMES = {"lead", "agent"}
def is_valid_agent_name(name: str) -> bool:
return bool(VALID_AGENT_NAME.fullmatch(name))
class MessageBus:
"""Thread-safe file mailboxes with destructive reads."""
def __init__(self):
self._lock = threading.RLock()
self._changed = threading.Condition(self._lock)
def _path(self, agent: str) -> Path:
if not is_valid_agent_name(agent):
raise ValueError(f"Invalid mailbox recipient: {agent!r}")
path = (MAILBOX_DIR / f"{agent}.jsonl").resolve()
if not path.is_relative_to(MAILBOX_ROOT):
raise ValueError(f"Mailbox path escapes directory: {agent!r}")
return path
def _read_unlocked(self, agent: str) -> list[dict]:
inbox = self._path(agent)
if not inbox.exists():
return []
msgs = [json.loads(line) for line in inbox.read_text().splitlines()
if line.strip()]
inbox.unlink()
return msgs
def send(self, from_agent: str, to_agent: str, content: str,
msg_type: str = "message", metadata: dict | None = None):
msg = {"from": from_agent, "to": to_agent,
"content": content, "type": msg_type,View on GitHub (pinned to 985456f4ad)
Solutions
- Use short machine names: lowercase letters, digits, underscore, hyphen only.
- Sanitize names at agent-registration time with the same regex before any send/receive.
- Map display names to safe slugs (e.g. re.sub(r'[^A-Za-z0-9_-]', '_', name)).
Example fix
// before
bus.send('alice', 'Agent One', 'hi') // ValueError
// after
import re
slug = re.sub(r'[^A-Za-z0-9_-]', '_', 'Agent One').strip('_') // 'Agent_One'
bus.send('alice', slug, 'hi') Defensive patterns
Strategy: type-guard
Validate before calling
import re
VALID_AGENT_NAME = re.compile(r'^[A-Za-z0-9_-]{1,64}$')
def valid_recipient(agent: str) -> bool:
return isinstance(agent, str) and bool(VALID_AGENT_NAME.fullmatch(agent)) Type guard
import re
from typing import TypeGuard
_AGENT_RE = re.compile(r'^[A-Za-z0-9_-]{1,64}$')
def is_agent_name(value: object) -> TypeGuard[str]:
return isinstance(value, str) and bool(_AGENT_RE.fullmatch(value)) Prevention
- Register agent names once, validated against ^[A-Za-z0-9_-]{1,64}$.
- Slugify display names (re.sub(r'[^A-Za-z0-9_-]', '_', name)) before using them on the bus.
- Reject user-typed names with spaces/@/dots at the input boundary.
When it happens
Trigger: bus.send('alice', 'agent one', 'hi') (space); recipient 'a/b' or 'a..b' (slash/dots); empty string; an email-style 'alice@team' ('@' not allowed); a 65-char name.
Common situations: Deriving agent names from free-form display names or emails; forwarding user-typed names; whitespace from copy-paste.
Related errors
- Path escapes workspace: {p}
- Path escapes workspace: {p}
- Path escapes workspace: {p}
- Path escapes workspace: {p}
- Invalid mailbox recipient: {agent!r}
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/45ad9a5056bff36e.
Report an issue: GitHub.