HKUDS/Vibe-Trading · error · ValueError
Invalid swarm agent id {agent_id!r}: artifact path escapes t
Error message
Invalid swarm agent id {agent_id!r}: artifact path escapes the run artifacts directory What it means
Raised by agent_artifact_dir in agent/src/swarm/worker.py when the resolved artifact directory for a swarm agent id does not lie inside the resolved run artifacts root. It is a path-traversal guard: agent ids like '../foo', '/etc', or symlinked paths that canonicalize outside the root are rejected.
Source
Thrown at agent/src/swarm/worker.py:379
artifact_root = run_dir / "artifacts"
if (
not isinstance(agent_id, str)
or not agent_id
or agent_id in {".", ".."}
or "/" in agent_id
or "\\" in agent_id
):
raise ValueError(
f"Invalid swarm agent id {agent_id!r}: expected one safe path segment"
)
artifact_dir = artifact_root / agent_id
resolved_root = artifact_root.resolve()
resolved_dir = artifact_dir.resolve()
try:
relative = resolved_dir.relative_to(resolved_root)
except ValueError as exc:
raise ValueError(
f"Invalid swarm agent id {agent_id!r}: artifact path escapes "
"the run artifacts directory"
) from exc
if len(relative.parts) != 1:
raise ValueError(
f"Invalid swarm agent id {agent_id!r}: artifact path must be "
"one level below the run artifacts directory"
)
return artifact_dir
def clear_agent_artifacts(artifact_dir: Path) -> None:
"""Remove *artifact_dir* and everything in it, before a retry attempt.
A retry re-invokes :func:`run_worker` against the same ``artifact_dir``.
Without this, a failed attempt's ``report.md`` (or any other file a tool
wrote) would still be sitting there when the retried attempt reads the
directory back via ``_resolve_summary``/``_report_written``/View on GitHub (pinned to 80ffdda44c)
Solutions
- Sanitize/validate agent ids to a simple identifier charset (e.g. r'^[A-Za-z0-9_-]+$') before calling the swarm worker
- If the id legitimately contains separators, derive a safe slug or hash instead of using the raw string
- Remove or relocate symlinks inside the artifacts root so resolution stays contained
Example fix
// before
artifact_dir = agent_artifact_dir(root, agent_id) # agent_id = '../evil'
// after
import re
if not re.fullmatch(r'[A-Za-z0-9_.-]+', agent_id):
raise ValueError(f'bad agent id: {agent_id!r}')
artifact_dir = agent_artifact_dir(root, agent_id) Defensive patterns
Strategy: validation
Validate before calling
import re
SAFE_ID = re.compile(r'^[A-Za-z0-9_-]+$')
assert SAFE_ID.fullmatch(agent_id), f'unsafe agent id: {agent_id!r}' Type guard
def is_safe_agent_id(agent_id: str) -> bool:
return bool(re.fullmatch(r'[A-Za-z0-9_-]+', agent_id)) and '..' not in agent_id Try / catch
try:
d = agent_artifact_dir(root, agent_id)
except ValueError as e:
log.warning('rejecting agent id %r: %s', agent_id, e)
agent_id = hashlib.sha256(agent_id.encode()).hexdigest()[:16]
d = agent_artifact_dir(root, agent_id) Prevention
- Never pass raw LLM/user strings as filesystem path components
- Normalize agent ids to a fixed charset at ingestion time
- Keep the artifacts root free of symlinks you don't control
When it happens
Trigger: Calling agent_artifact_dir (directly or via _run_worker_with_retries/_run_worker_impl) with an agent_id containing '/', '..', leading '/', or an id that resolves through a symlink to a location outside artifact_root.resolve().
Common situations: Passing an LLM-generated or user-supplied agent id unchecked into the swarm worker; agent ids built from file paths; a symlink placed inside the artifacts directory escaping the run dir.
Related errors
- artifact_path escapes the current run_dir
- invalid shadow_id
- SWARM_WORKER_RETRY_MAX_DELAY_S must be greater than or equal
- {source} produces an invalid multiline HTTP header ({name!r}
- Invalid swarm agent id {agent_id!r}: expected one safe path
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/df8d97c839291e1b.
Report an issue: GitHub.