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

  1. Sanitize/validate agent ids to a simple identifier charset (e.g. r'^[A-Za-z0-9_-]+$') before calling the swarm worker
  2. If the id legitimately contains separators, derive a safe slug or hash instead of using the raw string
  3. 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

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


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/df8d97c839291e1b. Report an issue: GitHub.