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 before constructing a mailbox filename. A recipient failing the regex (wrong characters, wrong shape, empty, non-string) is rejected as 'Invalid mailbox recipient' — this is the first, purely lexical guard, applied on both send() and read paths.
Source
Thrown at s15_integrated_harness/code.py:1024
MAILBOX_DIR = WORKDIR / ".mailboxes"
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:
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 exactly the agent names the harness registered (re-check the teammates list / VALID_AGENT_NAME pattern).
- Validate the recipient caller-side with the same regex before send().
- Treat a failure as 'unknown teammate' and re-list valid names rather than retrying the same string.
Example fix
// before
bus.send("agent-a", "Bob", "hi") // invalid recipient
// after
if is_valid_agent_name("teammate_bob"):
bus.send("agent-a", "teammate_bob", "hi") Defensive patterns
Strategy: type-guard
Validate before calling
from s15_integrated_harness.code import is_valid_agent_name
if not is_valid_agent_name(to_agent):
raise ValueError(f"unknown teammate {to_agent!r}; check registered names") Type guard
def is_agent_name(name) -> bool:
return isinstance(name, str) and bool(is_valid_agent_name(name)) Try / catch
try:
bus.send(from_agent, to_agent, content)
except ValueError as e:
if "Invalid mailbox recipient" in str(e):
# re-list valid agent names and re-address
raise Prevention
- Address teammates only by registered names.
- Re-use is_valid_agent_name() as the caller-side guard.
- Don't derive recipient names from freeform text.
When it happens
Trigger: Calling send(to_agent="../evil") or names with spaces, slashes, unicode, or an empty string; passing a None or non-str agent; model-generated recipient names not matching the teammate naming convention.
Common situations: Agent messaging a teammate by freeform nickname instead of its registered name; typos; passing an agent object instead of its name string.
Related errors
- Invalid mailbox recipient: {agent!r}
- MCP names cannot normalize to an empty string
- MCP tool name is longer than 64 characters: {prefixed}
- MCP tool name collision after normalization: {prefixed!r} ma
- invalid workflow runId
AI-assisted analysis of shareAI-lab/learn-claude-code@985456f4ad (2026-08-14).
Data as JSON: /api/errors/ac23e689071edaeb.
Report an issue: GitHub.