redis/redis-py · error · DataError

``ordering`` (OBO or BULK) is required when ``count`` is set

Error message

``ordering`` (OBO or BULK) is required when ``count`` is set

What it means

Raised as a `DataError` by `lmovem()` (redis/commands/core.py:3675) when `count` is set but `ordering` is `None`. Multi-element LMOVEM requires an explicit destination ordering — `OBO` (one-by-one, stack semantics) or `BULK` (preserve order, queue semantics) — because the server cannot guess push semantics.

Solutions

  1. Always pass `ordering='OBO'` or `ordering='BULK'` together with `count`.
  2. Choose `OBO` to reverse block order at the destination, `BULK` to preserve it.
  3. Drop `count` if you only want a single-element move.

Example fix

// before
r.lmovem('src', 'dst', count=3)
// after
r.lmovem('src', 'dst', count=3, ordering='BULK')  # preserve relative order
Defensive patterns

Strategy: validation

Validate before calling

if count is not None and ordering is None:
    raise ValueError("lmovem: ordering must be 'OBO' or 'BULK' when count is set")
r.lmovem('a', 'b', count=count, ordering=ordering)

Prevention

When it happens

Trigger: `r.lmovem('a', 'b', count=3)`, or any LMOVEM call that supplies count but omits ordering (mode is optional and defaults to COUNT).

Common situations: Forwarding only count from a caller; assuming a default ordering; refactoring from LMPOP-style code.

Related errors


AI-assisted analysis of redis/redis-py@6a6b581b48 (2026-08-10). Data as JSON: /api/errors/424696bcaa91cbb1. Report an issue: GitHub.

Appendix: source

Thrown at redis/commands/core.py:3676

        ``EXACTLY`` moves exactly ``count`` elements or nothing at all. When
        ``count`` is not given a single element is moved.

        ``ordering`` controls the order at the destination: ``OBO`` pushes each
        element as it is popped (reversing block order, stack semantics) while
        ``BULK`` preserves the original relative order (queue semantics). It is
        required whenever ``count`` is given.

        Returns the array of moved elements, or ``None`` if nothing was moved.

        For more information, see https://redis.io/commands/lmovem
        """
        if count is None:
            if mode is not None or ordering is not None:
                raise DataError(
                    "``count`` is required when ``mode`` or ``ordering`` is set"
                )
        elif ordering is None:
            raise DataError(
                "``ordering`` (OBO or BULK) is required when ``count`` is set"
            )
        pieces: list[EncodableT] = [first_list, second_list, src, dest]
        if count is not None:
            pieces.extend([mode or "COUNT", count, ordering])
        return self.execute_command("LMOVEM", *pieces)

    @overload
    def blmovem(
        self: SyncClientProtocol,
        first_list: str,
        second_list: str,
        timeout: float,
        src: str = "LEFT",
        dest: str = "RIGHT",
        count: int | None = None,
        mode: Literal["COUNT", "EXACTLY"] | None = None,
        ordering: Literal["OBO", "BULK"] | None = None,

View on GitHub (pinned to 6a6b581b48)