affaan-m/ECC · error · ValueError

workflow needs at least one numbered genre

Error message

workflow needs at least one numbered genre

What it means

run_workflow requires config['genres'] to be a non-empty list after sorting by each item's 'number' key. An empty genres list (or missing key defaulting to []) fails this check, since the workflow has nothing to emit manifests for.

Solutions

  1. Add at least one genre dict to config['genres'], each with 'number', 'slug' and 'references' keys
  2. Check that the JSON/YAML workflow file actually contains a populated genres array
  3. Ensure the config-merging code does not overwrite a populated genres list with []

Example fix

// before
config = {'schema_version': 1, 'dry_run': True, 'genres': []}
// after
config = {'schema_version': 1, 'dry_run': True, 'genres': [{'number': 1, 'slug': 'noir', 'references': []}]}
Defensive patterns

Strategy: validation

Validate before calling

genres = config.get('genres') or []
if not genres:
    raise ValueError('config.genres must contain at least one genre')

Type guard

def has_genres(config) -> bool:
    g = config.get('genres')
    return isinstance(g, list) and len(g) > 0 and all(isinstance(x, dict) for x in g)

Try / catch

try:
    run_workflow(config, out_dir)
except ValueError as e:
    if 'at least one numbered genre' in str(e):
        raise UserInputError('Populate the genres array in your workflow file') from e
    raise

Prevention

When it happens

Trigger: Calling run_workflow with config lacking 'genres', or with genres=[] or genres=None.

Common situations: Generated config from a template that left genres unpopulated; a JSON workflow file where the genres array was emptied; forgetting to merge genre entries when constructing config programmatically.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/b1abc30e15db6224. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/tasteforge/workflow.py:545

    config = json.loads(config_path.read_text(encoding="utf-8"))
    probe = probe or probe_media

    def resolve_input(raw_path: str) -> Path:
        candidate = Path(raw_path).expanduser()
        if not candidate.is_absolute():
            candidate = config_path.parent / candidate
        return Path(os.path.abspath(candidate))

    if config.get("schema_version") != 1:
        raise ValueError("workflow schema_version must be 1")
    if config.get("dry_run", True) is not True:
        raise ValueError("workflow requires dry_run=true; provider execution is disabled")
    source_policy = config.get("source_availability_policy", "allow_unavailable")
    if source_policy not in {"allow_unavailable", "require_available"}:
        raise ValueError("source_availability_policy must be allow_unavailable or require_available")
    genres = sorted(config.get("genres", []), key=lambda item: item["number"])
    if not genres:
        raise ValueError("workflow needs at least one numbered genre")

    output = _SafeOutput(out_dir)
    output.prepare(("genres", "manifests", "resolve"))

    references: list[dict[str, Any]] = []
    specs: list[dict[str, Any]] = []
    manifests: dict[str, dict[str, Any]] = {
        modality: {
            "schema_version": 1,
            "modality": modality,
            "dry_run": True,
            "submit": False,
            "provider_calls": 0,
            "provider_execution": False,
            "requests": [],
        }
        for modality in _MODALITIES
    }

View on GitHub (pinned to 8321021c54)