HKUDS/Vibe-Trading · error · ValueError

run_id must not be empty

Error message

run_id must not be empty

What it means

build_run_manifest requires a non-empty run_id (after strip). Empty or whitespace-only ids are rejected because the manifest must be attributable to a concrete run.

Source

Thrown at agent/src/governance/manifest.py:392

            caller already has the injected skills' full bodies) or a
            pre-built sequence of :class:`SkillRecord`.
        tool_names: Tool registry names, e.g. ``ToolRegistry.tool_names``.
        package_versions: ``{package: version_or_None}``; see
            :func:`collect_key_package_versions` for a ready-made curated
            collector.
        extra: Small caller-defined composition dimensions (e.g.
            ``{"provider": "openrouter", "model": "deepseek/deepseek-v3.2"}``).

    Returns:
        A new :class:`RunManifest` with ``manifest_hash`` computed over the
        composition (excluding ``run_id``/``timestamp``).

    Raises:
        ValueError: ``run_id``/``timestamp`` is empty, or ``skills`` contains
            two records with the same name.
    """
    if not run_id or not run_id.strip():
        raise ValueError("run_id must not be empty")
    if not timestamp or not timestamp.strip():
        raise ValueError("timestamp must not be empty")

    if isinstance(skills, Mapping):
        skill_records = tuple(
            sorted(
                (SkillRecord.from_content(name, content) for name, content in skills.items()),
                key=lambda record: record.name,
            )
        )
    else:
        skill_records = tuple(sorted(skills, key=lambda record: record.name))
        names = [record.name for record in skill_records]
        if len(names) != len(set(names)):
            raise ValueError(f"duplicate skill names in manifest input: {names}")

    tools_snapshot = ToolRegistrySnapshot.from_names(tool_names)
    pv_pairs = _pairs(package_versions)

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Generate the run id up front (uuid or run registry) and thread it through to the manifest call
  2. Validate run_id.strip() at the entry point of the run, not at manifest time
  3. Fail fast in tests with a fixture-provided non-empty id

Example fix

# before
manifest = build_run_manifest(run_id=run_id, ...)  # run_id == ""
# after
run_id = run_id or f"run-{uuid.uuid4().hex}"
manifest = build_run_manifest(run_id=run_id, ...)
Defensive patterns

Strategy: validation

Validate before calling

run_id = (run_id or "").strip() or f"run-{uuid.uuid4().hex}"

Type guard

def is_valid_run_id(run_id: str) -> bool:
    return bool(run_id and run_id.strip())

Try / catch

except ValueError as e: if 'run_id' in str(e): generate an id and retry build_run_manifest

Prevention

When it happens

Trigger: Calling build_run_manifest(run_id=""), run_id=" ", or passing an unpopulated variable (None-ish default resolved to empty string).

Common situations: run id generated only in a code path not taken (e.g. resumed run); env/config supplying an empty RUN_ID; tests calling the builder with placeholder ids.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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