HKUDS/Vibe-Trading · error · ValueError

Invalid swarm agent id {agent_id!r}: artifact path must be o

Error message

Invalid swarm agent id {agent_id!r}: artifact path must be one level below the run artifacts directory

What it means

Raised by agent_artifact_dir when the agent's artifact directory resolves correctly under the root but is nested more than one level deep. The API requires each agent to own exactly one directory directly beneath the run artifacts root, so ids like 'a/b' (even when legitimately contained) are rejected.

Source

Thrown at agent/src/swarm/worker.py:384

        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``/
    ``_collect_artifacts``, silently substituting stale content for the new
    attempt's real result.

    Raises on failure rather than swallowing it: proceeding with a retry
    while known-stale artifacts remain would recreate the exact bug this

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Flatten the agent id to a single path component (replace '/' with '-' or '_')
  2. Use a registry mapping hierarchical names to flat artifact directory names
  3. Catch the ValueError and re-raise a user-facing message explaining ids must be flat

Example fix

// before
agent_id = f'{team}/{worker}'  # 'red/team-1'
// after
agent_id = f'{team}__{worker}'  # 'red__team-1'
Defensive patterns

Strategy: validation

Validate before calling

agent_id = agent_id.replace('/', '__').replace('\\', '__')
assert '/' not in agent_id and len(Path(agent_id).parts) == 1

Type guard

def is_flat_id(agent_id: str) -> bool:
    return isinstance(agent_id, str) and '/' not in agent_id and agent_id not in ('.', '..')

Try / catch

try:
    d = agent_artifact_dir(root, agent_id)
except ValueError:
    d = agent_artifact_dir(root, slugify(agent_id))

Prevention

When it happens

Trigger: Calling agent_artifact_dir with an agent_id that contains a path separator but still resolves inside the root, e.g. 'sub/agent1' or 'foo/.'; relative.parts ends up with more than one component after resolution.

Common situations: Agent ids composed from team/role hierarchies (e.g. 'team-a/worker-1'); ids with trailing '/.' or redundant segments that resolve to nested paths.

Related errors


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