{"record":{"id":"ac23e689071edaeb","repo":"shareAI-lab/learn-claude-code","slug":"invalid-mailbox-recipient-agent-r-ac23e6","errorCode":null,"errorMessage":"Invalid mailbox recipient: {agent!r}","messagePattern":"Invalid mailbox recipient: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"s15_integrated_harness/code.py","lineNumber":1024,"sourceCode":"\nMAILBOX_DIR = WORKDIR / \".mailboxes\"\nMAILBOX_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    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":1006,"sourceCodeEnd":1042,"githubUrl":"https://github.com/shareAI-lab/learn-claude-code/blob/985456f4adea6f4df8fbad4112245dbd97444eae/s15_integrated_harness/code.py#L1006-L1042","documentation":"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.","triggerScenarios":"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.","commonSituations":"Agent messaging a teammate by freeform nickname instead of its registered name; typos; passing an agent object instead of its name string.","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."],"exampleFix":"// before\nbus.send(\"agent-a\", \"Bob\", \"hi\")  // invalid recipient\n\n// after\nif is_valid_agent_name(\"teammate_bob\"):\n    bus.send(\"agent-a\", \"teammate_bob\", \"hi\")","handlingStrategy":"type-guard","validationCode":"from s15_integrated_harness.code import is_valid_agent_name\n\nif not is_valid_agent_name(to_agent):\n    raise ValueError(f\"unknown teammate {to_agent!r}; check registered names\")","typeGuard":"def is_agent_name(name) -> bool:\n    return isinstance(name, str) and bool(is_valid_agent_name(name))","tryCatchPattern":"try:\n    bus.send(from_agent, to_agent, content)\nexcept ValueError as e:\n    if \"Invalid mailbox recipient\" in str(e):\n        # re-list valid agent names and re-address\n        raise","preventionTips":["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."],"tags":["message-bus","validation","naming"],"backgroundTag":null,"analyzedSha":"985456f4adea6f4df8fbad4112245dbd97444eae","analyzedAt":"2026-08-14T22:02:26.028Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}