microsoft/autogen · error · ValueError

expand_scenario expects an str or list for 'template'

Error message

expand_scenario expects an str or list for 'template'

What it means

Raised in agbench's scenario expansion when the 'template' field of a scenario is neither a string nor a list. The expander handles str (a file or directory path within the scenario dir) and list (of [source, dest] pairs or plain strings); any other JSON type (number, object, bool, null-as-non-None) is rejected with ValueError.

Source

Thrown at python/packages/agbench/src/agbench/run_cmd.py:215

        substitutions = {"scenario.py": cast(Dict[str, str], substitutions)}

    copy_operations: List[Tuple[str, str]] = []

    # Handle file (str), folder (str), or mapping (List) templates
    if isinstance(template, str):
        template_path = os.path.join(scenario_dir, template)
        if os.path.isdir(template_path):
            copy_operations.append((template, ""))
        else:
            copy_operations.append((template, "scenario.py"))
    elif isinstance(template, list):
        for elm in template:
            if isinstance(elm, list):
                copy_operations.append((elm[0], elm[1]))
            else:
                copy_operations.append((elm, ""))
    else:
        raise ValueError("expand_scenario expects an str or list for 'template'")

    # The global includes folder is always copied
    shutil.copytree(
        BASE_TEMPLATE_PATH,
        output_dir,
        ignore=shutil.ignore_patterns("*.example"),
        dirs_exist_ok=False,
    )

    # Expand other folders
    for items in copy_operations:
        src_path = pathlib.Path(os.path.join(scenario_dir, items[0])).absolute()
        dest_path = pathlib.Path(os.path.join(output_dir, items[1])).absolute()

        if os.path.isdir(src_path):
            shutil.copytree(src_path, dest_path, dirs_exist_ok=True)
        else:
            if os.path.isdir(dest_path):

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Set "template" to a string path relative to the scenario dir, e.g. "coding" or "scenario.py".
  2. Or use a list form: ["dir_or_file", ...] or [["src", "dest"], ...].
  3. Validate the scenario JSON against the expected schema before running (jsonschema or a quick isinstance check).

Example fix

// before
{"name": "bench", "template": {"path": "scenario.py"}}

// after
{"name": "bench", "template": "scenario.py"}
Defensive patterns

Strategy: validation

Validate before calling

import json
template = scenario.get("template")
if not isinstance(template, (str, list)):
    raise ValueError(f"scenario '{scenario.get('name')}': 'template' must be str or list, got {type(template).__name__}")

Type guard

def is_valid_template(t) -> bool:
    if isinstance(t, str):
        return True
    if isinstance(t, list):
        return all(isinstance(x, str) or (isinstance(x, list) and len(x) == 2 and all(isinstance(i, str) for i in x)) for x in t)
    return False

Try / catch

try:
    expand_scenario(...)
except ValueError as e:
    if "expects an str or list" in str(e):
        fix_scenario_template_and_rerun()
    else:
        raise

Prevention

When it happens

Trigger: A .jsonl scenario line whose "template" field is, e.g., a JSON object {"path": ...} or a number, or a template element list whose items are nested structures not of the form [str, str].

Common situations: Hand-editing scenario JSONL and using an object form from different tooling docs, YAML->JSON conversion producing unexpected types, or schema drift between scenario format versions.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/f93c157a9132a344. Report an issue: GitHub.