{"record":{"id":"45ad9a5056bff36e","repo":"shareAI-lab/learn-claude-code","slug":"invalid-mailbox-recipient-agent-r","errorCode":null,"errorMessage":"Invalid mailbox recipient: {agent!r}","messagePattern":"Invalid mailbox recipient: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"s13_agent_teams/code.py","lineNumber":792,"sourceCode":"MAILBOX_ROOT = MAILBOX_DIR.resolve()\nVALID_AGENT_NAME = re.compile(r\"^[A-Za-z0-9_-]{1,64}$\")\nRESERVED_TEAMMATE_NAMES = {\"lead\", \"agent\"}\n\n\ndef is_valid_agent_name(name: str) -> bool:\n    return bool(VALID_AGENT_NAME.fullmatch(name))\n\n\nclass MessageBus:\n    \"\"\"Thread-safe file mailboxes with destructive reads.\"\"\"\n\n    def __init__(self):\n        self._lock = threading.RLock()\n        self._changed = threading.Condition(self._lock)\n\n    def _path(self, agent: str) -> Path:\n        if not is_valid_agent_name(agent):\n            raise ValueError(f\"Invalid mailbox recipient: {agent!r}\")\n        path = (MAILBOX_DIR / f\"{agent}.jsonl\").resolve()\n        if not path.is_relative_to(MAILBOX_ROOT):\n            raise ValueError(f\"Mailbox path escapes directory: {agent!r}\")\n        return path\n\n    def _read_unlocked(self, agent: str) -> list[dict]:\n        inbox = self._path(agent)\n        if not inbox.exists():\n            return []\n        msgs = [json.loads(line) for line in inbox.read_text().splitlines()\n                if line.strip()]\n        inbox.unlink()\n        return msgs\n\n    def send(self, from_agent: str, to_agent: str, content: str,\n             msg_type: str = \"message\", metadata: dict | None = None):\n        msg = {\"from\": from_agent, \"to\": to_agent,\n               \"content\": content, \"type\": msg_type,","sourceCodeStart":774,"sourceCodeEnd":810,"githubUrl":"https://github.com/shareAI-lab/learn-claude-code/blob/985456f4adea6f4df8fbad4112245dbd97444eae/s13_agent_teams/code.py#L774-L810","documentation":"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.","triggerScenarios":"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.","commonSituations":"Deriving agent names from free-form display names or emails; forwarding user-typed names; whitespace from copy-paste.","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))."],"exampleFix":"// before\nbus.send('alice', 'Agent One', 'hi')  // ValueError\n\n// after\nimport re\nslug = re.sub(r'[^A-Za-z0-9_-]', '_', 'Agent One').strip('_')  // 'Agent_One'\nbus.send('alice', slug, 'hi')","handlingStrategy":"type-guard","validationCode":"import re\nVALID_AGENT_NAME = re.compile(r'^[A-Za-z0-9_-]{1,64}$')\n\ndef valid_recipient(agent: str) -> bool:\n    return isinstance(agent, str) and bool(VALID_AGENT_NAME.fullmatch(agent))","typeGuard":"import re\nfrom typing import TypeGuard\n_AGENT_RE = re.compile(r'^[A-Za-z0-9_-]{1,64}$')\n\ndef is_agent_name(value: object) -> TypeGuard[str]:\n    return isinstance(value, str) and bool(_AGENT_RE.fullmatch(value))","tryCatchPattern":null,"preventionTips":["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."],"tags":["validation","message-bus","agent-names","security"],"backgroundTag":null,"analyzedSha":"985456f4adea6f4df8fbad4112245dbd97444eae","analyzedAt":"2026-08-14T22:02:26.028Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}