{"id":"d0a0ad331642c8e9","repo":"redis/redis-py","slug":"at-least-one-tag-must-be-specified","errorCode":null,"errorMessage":"At least one tag must be specified","messagePattern":"At least one tag must be specified","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"redis/commands/search/querystring.py","lineNumber":10,"sourceCode":"def tags(*t):\n    \"\"\"\n    Indicate that the values should be matched to a tag field\n\n    ### Parameters\n\n    - **t**: Tags to search for\n    \"\"\"\n    if not t:\n        raise ValueError(\"At least one tag must be specified\")\n    return TagValue(*t)\n\n\ndef between(a, b, inclusive_min=True, inclusive_max=True):\n    \"\"\"\n    Indicate that value is a numeric range\n    \"\"\"\n    return RangeValue(a, b, inclusive_min=inclusive_min, inclusive_max=inclusive_max)\n\n\ndef equal(n):\n    \"\"\"\n    Match a numeric value\n    \"\"\"\n    return between(n, n)\n\n\ndef lt(n):","sourceCodeStart":1,"sourceCodeEnd":28,"githubUrl":"https://github.com/redis/redis-py/blob/da03cdc7e8731092b13e395605c3c1fb2de25de1/redis/commands/search/querystring.py#L1-L28","documentation":"Raised by redis.commands.search.querystring.tags() when called with no tag arguments. The function builds a tag-value expression {@field:{tag1|tag2}} and requires at least one tag to be meaningful. Passing zero tags is treated as a caller bug.","triggerScenarios":"Calling tags() with no positional args, or tags(*[]) / tags(*empty_list) where the list unpacks to nothing, typically inside a dynamic query builder.","commonSituations":"Building a tag filter from user input where the user selected no tags; iterating over an empty collection and forwarding it to tags(); conditional tag logic that forgets the empty case.","solutions":["Ensure at least one tag is passed: tags('red', 'blue').","Guard dynamic inputs: only call tags(*selected) when selected is non-empty, otherwise omit the tag clause.","Default to a sentinel/wildcard if an empty selection should match all."],"exampleFix":"// before\nexpr = tags(*selected_tags)  # fails when empty\n// after\nexpr = tags(*selected_tags) if selected_tags else None","handlingStrategy":"validation","validationCode":"from redis.commands.search import querystring\n\ndef safe_tags(*t):\n    if not t:\n        return None  # caller omits the clause\n    return querystring.tags(*t)","typeGuard":"def has_tags(t) -> bool:\n    return bool(t)","tryCatchPattern":"try:\n    node = querystring.tags(*selected)\nexcept ValueError:\n    node = None  # no tag clause","preventionTips":["Check the tag list is non-empty before calling tags().","Treat an empty tag selection as 'omit the clause', not as an error to surface.","Unit-test dynamic query builders with empty inputs."],"tags":["search","search-and-query","querystring","tag","argument-error"],"analyzedSha":"da03cdc7e8731092b13e395605c3c1fb2de25de1","analyzedAt":"2026-08-04T20:26:47.563Z","schemaVersion":2}