{"record":{"id":"1a6b4dc543ca0b6b","repo":"HKUDS/Vibe-Trading","slug":"run-id-run-id-r-must-be-a-bare-run-directory-nam","errorCode":null,"errorMessage":"run_id {run_id!r} must be a bare run directory name","messagePattern":"run_id (.+?) must be a bare run directory name","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/swarm/store.py","lineNumber":156,"sourceCode":"        Args:\n            run_id: Run identifier.\n\n        Returns:\n            Path to the run directory.\n\n        Raises:\n            ValueError: If run_id is empty, absolute, or path-shaped.\n        \"\"\"\n        candidate = Path(run_id)\n        if (\n            not run_id.strip()\n            or candidate.is_absolute()\n            or len(candidate.parts) != 1\n            or any(part in {\"\", \".\", \"..\"} for part in candidate.parts)\n            or \"/\" in run_id\n            or \"\\\\\" in run_id\n        ):\n            raise ValueError(f\"run_id {run_id!r} must be a bare run directory name\")\n        return self.base_dir / candidate.name\n\n    def create_run(self, run: SwarmRun) -> Path:\n        \"\"\"Create the directory structure for a new run and write initial state.\n\n        Args:\n            run: SwarmRun instance.\n\n        Returns:\n            Path to the created run directory.\n\n        Raises:\n            FileExistsError: If the run directory already exists.\n        \"\"\"\n        rd = self.run_dir(run.id)\n        rd.mkdir(parents=True, exist_ok=False)\n        (rd / \"tasks\").mkdir()\n        (rd / \"inboxes\").mkdir()","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/swarm/store.py#L138-L174","documentation":"SwarmStore.run_dir guards against path injection: run_id must be a single safe path segment (no absolute paths, no multiple parts, no '', '.', '..', '/', or '\\\\'). Violations raise ValueError before the id is joined onto base_dir.","triggerScenarios":"run_dir('runs/abc'), run_id='/abs/path', run_id containing '..' or a Windows backslash, or an empty run id.","commonSituations":"Passing a full path or a nested id from user input or logs; reusing a Path object's string form that happens to be absolute.","solutions":["Pass only the bare directory name, e.g. '2024-05-01T10-00-00-abc123'","Generate ids via the store's create_run instead of constructing them externally","Sanitize/validate external run ids before any store call"],"exampleFix":"# before\nstore.run_dir('/var/runs/abc')\n# after\nstore.run_dir('abc')","handlingStrategy":"type-guard","validationCode":"import re\nif not re.fullmatch(r'[A-Za-z0-9._-]+', run_id or '') or run_id in {'.','..'}:\n    raise ValueError('unsafe run_id')","typeGuard":"def is_bare_run_id(rid) -> bool:\n    return (isinstance(rid, str) and rid not in {'','.','..'} and '/' not in rid and '\\\\' not in rid and len(Path(rid).parts) == 1)","tryCatchPattern":"try:\n    store.run_dir(run_id)\nexcept ValueError as e:\n    if 'bare run directory name' in str(e): reject/sanitize the id\n    else: raise","preventionTips":["Generate run ids via create_run, never from paths","Validate externally sourced ids with a whitelist regex","Keep run ids to slugs/uuids"],"tags":["python","path-traversal","input-validation"],"backgroundTag":"path-traversal-rejected","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}