{"record":{"id":"eaea3f91263df6f5","repo":"HKUDS/Vibe-Trading","slug":"run-id-run-id-r-must-be-a-bare-run-directory-nam-eaea3f","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/tools/path_utils.py","lineNumber":392,"sourceCode":"\n    Args:\n        run_id: Bare run directory name, not a path.\n\n    Returns:\n        Existing run directory under one of the allowed run roots.\n\n    Raises:\n        ValueError: If the run id is empty, path-shaped, or not found.\n    \"\"\"\n    _rejects_unc(run_id)\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    ):\n        raise ValueError(f\"run_id {run_id!r} must be a bare run directory name\")\n\n    roots = _allowed_run_roots()\n    for root in roots:\n        resolved = (root / candidate.name).resolve()\n        if resolved.is_relative_to(root) and resolved.is_dir():\n            return resolved\n\n    raise ValueError(\n        f\"run_id {run_id!r} was not found under allowed run roots.\\n\"\n        f\"{_describe_roots(roots)}\"\n    )\n","sourceCodeStart":374,"sourceCodeEnd":404,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/path_utils.py#L374-L404","documentation":"safe_run_id expects a single path component: it rejects blank strings, absolute paths, multi-part names, and '.', '..' components. Anything path-shaped fails fast before filesystem lookup because a run_id maps to a directory name under allowed run roots.","triggerScenarios":"run_id='runs/run-42', run_id='/abs/path', run_id='', run_id='.', or run_id='run/../run'.","commonSituations":"Passing a full path where an identifier is expected, or trimming user input to an empty string.","solutions":["Pass just the directory name, e.g. run_id='run-42'","Derive it via Path(run_dir).name","Sanitize: reject run_ids containing '/', '\\\\', or that strip to empty"],"exampleFix":"# before\nsafe_run_id(\"/var/runs/run-42\")\n# after\nsafe_run_id(\"run-42\")","handlingStrategy":"type-guard","validationCode":"import re\nif not re.fullmatch(r\"[^/\\\\]+\", run_id.strip()) or run_id.strip() in {\".\", \"..\"}:\n    raise ArgumentError(\"run_id must be a bare directory name\")","typeGuard":"def is_bare_run_id(rid: str) -> bool:\n    rid = rid.strip()\n    return bool(rid) and not rid.startswith((\"/\", \"\\\\\")) and len(Path(rid).parts) == 1 and rid not in {\".\", \"..\"}","tryCatchPattern":"try:\n    rd = safe_run_id(run_id)\nexcept ValueError as e:\n    if \"bare run directory name\" in str(e):\n        rd = safe_run_id(Path(run_id).name)","preventionTips":["Pass identifiers, not paths","Derive run ids from creation responses","Reject '/' and '\\\\' in ids at input boundaries"],"tags":["run-id","path-validation","identifier"],"backgroundTag":"path-traversal-rejected","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}