{"id":"bd11357e53e16767","repo":"redis/redis-py","slug":"collect-fields-must-be-or-a-non-empty-list-of","errorCode":null,"errorMessage":"collect fields must be '*' or a non-empty list of names","messagePattern":"collect fields must be '\\*' or a non-empty list of names","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/commands/search/reducers.py","lineNumber":236,"sourceCode":"        - **distinct**: When ``True``, emit ``DISTINCT`` to deduplicate entries\n            with identical projected fields. Forward-compatible: this option is\n            not yet implemented by the server and currently produces a server\n            error when sent.\n        - **sort_by**: An ``Asc``/``Desc`` instance or an iterable of them, used\n            to order the collected entries within each group.\n        - **limit**: An ``(offset, count)`` pair. Returns at most ``count``\n            entries per group after skipping ``offset``. With ``sort_by`` this\n            acts as a top-N selection.\n        \"\"\"\n        args: list[str] = []\n\n        # FIELDS (required)\n        if fields == \"*\":\n            args += [\"FIELDS\", \"*\"]\n        else:\n            names = [fields] if isinstance(fields, str) else list(fields)\n            if not names or any(not n.strip() for n in names):\n                raise ValueError(\n                    \"collect fields must be '*' or a non-empty list of names\"\n                )\n            names = [_ensure_at_prefix(n) for n in names]\n            args += [\"FIELDS\", str(len(names))] + names\n\n        # DISTINCT (optional)\n        if distinct:\n            args += [\"DISTINCT\"]\n\n        # SORTBY (optional)\n        if sort_by is not None:\n            sort_fields = [sort_by] if isinstance(sort_by, (Asc, Desc)) else sort_by\n            sort_args: list[str] = []\n            for f in sort_fields:\n                sort_args += [_ensure_at_prefix(f.field), f.DIRSTRING]\n            if not sort_args:\n                raise ValueError(\"collect sort_by must contain at least one field\")\n            args += [\"SORTBY\", str(len(sort_args))] + sort_args","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/search/reducers.py#L218-L254","documentation":"Raised by the collect reducer constructor when the fields argument is a list/iterable that is empty or contains blank (whitespace-only) names. COLLECT projects fields from each grouped row, so at least one real field name (or the '*' wildcard) is mandatory. The literal '*' is handled separately and bypasses this check.","triggerScenarios":"collect(fields=[]) or collect(fields=['']) or collect(fields=['a', '  ']). Also collect(fields=names) where names resolved to an empty list at runtime.","commonSituations":"Dynamically generating the field list from user selection or schema introspection that returned nothing; stripping names and producing blanks; passing an empty generator.","solutions":["Pass '*' to project every field: collect(fields='*').","Supply a non-empty list of real names: collect(fields=['price', 'name']).","Validate before constructing: collect(fields=names) only when names and all(n.strip() for n in names)."],"exampleFix":"// before\ncollect(fields=selected or [])\n// after\ncollect(fields=selected if selected else '*')","handlingStrategy":"validation","validationCode":"def coerce_collect_fields(fields):\n    if fields in (None, '', []):\n        return '*'\n    if isinstance(fields, str):\n        return fields\n    names = [n for n in fields if n and n.strip()]\n    return names if names else '*'\n\n# usage: collect(fields=coerce_collect_fields(raw))","typeGuard":"def valid_collect_fields(fields) -> bool:\n    if fields == '*':\n        return True\n    names = [fields] if isinstance(fields, str) else list(fields or [])\n    return bool(names) and all(n.strip() for n in names)","tryCatchPattern":"try:\n    collect(fields=raw_fields)\nexcept ValueError:\n    collect(fields='*')","preventionTips":["Default to '*' when the field list is empty.","Strip/validate names before constructing the reducer.","Test aggregation builders with empty field selections."],"tags":["search","search-and-query","aggregation","reducer","collect","argument-error"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}