{"id":"63c1c71467e79dda","repo":"redis/redis-py","slug":"cannot-use-fieldname-alias-with-no-field","errorCode":null,"errorMessage":"Cannot use FIELDNAME alias with no field","messagePattern":"Cannot use FIELDNAME alias with no field","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/commands/search/aggregation.py","lineNumber":51,"sourceCode":"\n    def alias(self, alias: str) -> \"Reducer\":\n        \"\"\"\n        Set the alias for this reducer.\n\n        ### Parameters\n\n        - **alias**: The value of the alias for this reducer. If this is the\n            special value `aggregation.FIELDNAME` then this reducer will be\n            aliased using the same name as the field upon which it operates.\n            Note that using `FIELDNAME` is only possible on reducers which\n            operate on a single field value.\n\n        This method returns the `Reducer` object making it suitable for\n        chaining.\n        \"\"\"\n        if alias is FIELDNAME:\n            if not self._field:\n                raise ValueError(\"Cannot use FIELDNAME alias with no field\")\n            else:\n                # Chop off initial '@', which is optional in field names\n                alias = self._field.removeprefix(\"@\")\n        self._alias = alias\n        return self\n\n    @property\n    def args(self) -> Tuple[str, ...]:\n        return self._args\n\n\nclass SortDirection:\n    \"\"\"\n    This special class is used to indicate sort direction.\n    \"\"\"\n\n    DIRSTRING: Optional[str] = None\n","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/search/aggregation.py#L33-L69","documentation":"Raised by Reducer.alias() when called with the special sentinel aggregation.FIELDNAME but the reducer has no field bound to it. The FIELDNAME alias copies the reducer's operating field name, so it requires a single-field reducer (e.g. Count does not have one).","triggerScenarios":"Call reducer.alias(aggregation.FIELDNAME) on a reducer constructed without a field, such as Count() or any reducer whose _field attribute is None.","commonSituations":"Reusing a FIELDNAME alias template across all reducers in a pipeline including field-less reducers; refactoring that drops a reducer's field argument.","solutions":["Provide an explicit alias string instead of FIELDNAME for field-less reducers.","Ensure the reducer is constructed with a field before calling alias(FIELDNAME).","Guard: call alias(FIELDNAME) only when reducer._field is set."],"exampleFix":"// before\nCount().alias(aggregation.FIELDNAME)\n// after\nCount().alias(\"total\")","handlingStrategy":"validation","validationCode":"import redis.commands.search.aggregation as agg\n\ndef safe_alias(reducer, alias):\n    if alias is agg.FIELDNAME and not getattr(reducer, \"_field\", None):\n        raise ValueError(\"FIELDNAME alias requires a single-field reducer\")\n    return reducer.alias(alias)","typeGuard":"def reducer_has_field(reducer) -> bool:\n    return bool(getattr(reducer, \"_field\", None))","tryCatchPattern":"try:\n    reducer.alias(agg.FIELDNAME)\nexcept ValueError as e:\n    if \"FIELDNAME\" in str(e):\n        reducer.alias(\"value\")  # explicit fallback\n    else:\n        raise","preventionTips":["Don't apply FIELDNAME blindly across all reducers in a pipeline.","Field-less reducers (e.g. Count) need an explicit alias string.","Unit-test your aggregation builder with a mix of reducer types."],"tags":["redis-search","aggregation","validation","valueerror"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}