{"record":{"id":"0ff909dfedb09ef5","repo":"redis/redis-py","slug":"start-argument-is-not-set-when-end-is-specified","errorCode":null,"errorMessage":"start argument is not set, when end is specified","messagePattern":"start argument is not set, when end is specified","errorType":"validation","errorClass":"DataError","httpStatus":null,"severity":"error","filePath":"redis/commands/core.py","lineNumber":2791,"sourceCode":"    ) -> int | Awaitable[int]:\n        \"\"\"\n        Return the position of the first bit set to 1 or 0 in a string.\n        ``start`` and ``end`` defines search range. The range is interpreted\n        as a range of bytes and not a range of bits, so start=0 and end=2\n        means to look at the first three bytes.\n\n        For more information, see https://redis.io/commands/bitpos\n        \"\"\"\n        if bit not in (0, 1):\n            raise DataError(\"bit must be 0 or 1\")\n        params = [key, bit]\n\n        start is not None and params.append(start)\n\n        if start is not None and end is not None:\n            params.append(end)\n        elif start is None and end is not None:\n            raise DataError(\"start argument is not set, when end is specified\")\n\n        if mode is not None:\n            params.append(mode)\n        return self.execute_command(\"BITPOS\", *params, keys=[key])\n\n    @overload\n    def copy(\n        self: SyncClientProtocol,\n        source: str,\n        destination: str,\n        destination_db: str | None = None,\n        replace: bool = False,\n    ) -> bool: ...\n\n    @overload\n    def copy(\n        self: AsyncClientProtocol,\n        source: str,","sourceCodeStart":2773,"sourceCodeEnd":2809,"githubUrl":"https://github.com/redis/redis-py/blob/6a6b581b48225afa0b76912d1028c6035baee932/redis/commands/core.py#L2773-L2809","documentation":"Raised as a `DataError` by `bitpos()` (redis/commands/core.py:2790) when `start` is `None` but `end` is not. BITPOS requires a start before an end can be applied, so the client rejects an end-only range.","triggerScenarios":"`r.bitpos('k', 1, end=10)`, or any call leaving `start` at its default `None` while setting `end`.","commonSituations":"Keyword-only call style where the developer writes only `end=`; dynamic range building that sets `end` conditionally but always leaves `start` defaulted.","solutions":["Provide `start` whenever you provide `end`, e.g. `r.bitpos('k', 1, start=0, end=10)`.","Reorder logic so the end bound is only set when a start exists."],"exampleFix":"// before\nr.bitpos('k', 1, end=10)\n// after\nr.bitpos('k', 1, start=0, end=10)","handlingStrategy":"validation","validationCode":"if end is not None and start is None:\n    raise ValueError('bitpos: start is required when end is given')\nr.bitpos('k', 1, start=start, end=end)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always compute start before end.","Prefer positional `bitpos(k, bit, start, end)` to avoid keyword-only partial ranges."],"tags":["bitpos","arguments","validation","dataerror"],"backgroundTag":null,"analyzedSha":"6a6b581b48225afa0b76912d1028c6035baee932","analyzedAt":"2026-08-10T12:52:44.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}