{"record":{"id":"990dd65aa28f83a4","repo":"HKUDS/Vibe-Trading","slug":"invalid-swarm-agent-id-agent-id-r-expected-one","errorCode":null,"errorMessage":"Invalid swarm agent id {agent_id!r}: expected one safe path segment","messagePattern":"Invalid swarm agent id (.+?): expected one safe path segment","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/swarm/worker.py","lineNumber":369,"sourceCode":"\n    Args:\n        run_dir: Root directory for the swarm run.\n        agent_id: Single safe path segment identifying the agent.\n\n    Raises:\n        ValueError: If ``agent_id`` is not a single safe path segment or the\n            resolved artifact directory is not exactly one level below the\n            resolved ``run_dir/artifacts`` directory.\n    \"\"\"\n    artifact_root = run_dir / \"artifacts\"\n    if (\n        not isinstance(agent_id, str)\n        or not agent_id\n        or agent_id in {\".\", \"..\"}\n        or \"/\" in agent_id\n        or \"\\\\\" in agent_id\n    ):\n        raise ValueError(\n            f\"Invalid swarm agent id {agent_id!r}: expected one safe path segment\"\n        )\n\n    artifact_dir = artifact_root / agent_id\n    resolved_root = artifact_root.resolve()\n    resolved_dir = artifact_dir.resolve()\n    try:\n        relative = resolved_dir.relative_to(resolved_root)\n    except ValueError as exc:\n        raise ValueError(\n            f\"Invalid swarm agent id {agent_id!r}: artifact path escapes \"\n            \"the run artifacts directory\"\n        ) from exc\n    if len(relative.parts) != 1:\n        raise ValueError(\n            f\"Invalid swarm agent id {agent_id!r}: artifact path must be \"\n            \"one level below the run artifacts directory\"\n        )","sourceCodeStart":351,"sourceCodeEnd":387,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/swarm/worker.py#L351-L387","documentation":"agent_artifact_dir builds per-worker artifact directories and requires agent_id to be one safe path segment: a non-empty string that is not '.'/'..' and contains no '/' or '\\\\'. Violations raise ValueError before any filesystem access; a subsequent resolve() check also blocks symlink escapes out of the artifact root.","triggerScenarios":"Calling it with agent_id='worker/1', '..\\\\escape', '.', '', or a non-string; attacker-controlled ids from network input used as filenames.","commonSituations":"Passing composite worker names or URLs as agent ids; concurrent test runs probing path-shaped ids; ids containing backslashes on Linux after Windows-style generation.","solutions":["Use flat, sanitized ids like 'researcher-1' or 'worker-a3f'","Generate agent ids yourself (uuid/slug) instead of trusting external input","Normalize/validate ids at the boundary with the same rules (no separators, not ./..)"],"exampleFix":"# before\nagent_artifact_dir(root, agent_id='team/worker-1')\n# after\nagent_artifact_dir(root, agent_id='team-worker-1')","handlingStrategy":"type-guard","validationCode":"import re\nagent_id = re.sub(r'[^A-Za-z0-9._-]', '-', agent_id or '').strip('-.') or 'worker-anon'","typeGuard":"def is_safe_agent_id(a) -> bool:\n    return (isinstance(a, str) and bool(a) and a not in {'.','..'} and '/' not in a and '\\\\' not in a)","tryCatchPattern":"try:\n    agent_artifact_dir(root, agent_id)\nexcept ValueError as e:\n    if 'Invalid swarm agent id' in str(e): agent_id = slugify(agent_id); retry\n    else: raise","preventionTips":["Generate agent ids internally (uuid/slug), never from raw input","Apply the same one-segment rule at every boundary that names directories","Fuzz-test ids containing separators and dot segments"],"tags":["python","path-traversal","input-validation","swarm"],"backgroundTag":"path-traversal-rejected","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}