redis/redis-py · error · DataError

with_labels and select_labels cannot be provided together.

Error message

with_labels and select_labels cannot be provided together.

What it means

Raised by _append_with_labels when both with_labels=True and select_labels (a non-empty list) are supplied to TS.MRANGE/TS.MREVRANGE. WITHLABELS returns all label-value pairs while SELECTED_LABELS returns only a subset; they are mutually exclusive on the wire. Choose one.

Source

Thrown at redis/commands/timeseries/commands.py:1947

            )
        params.append("FILTER")
        params.extend(filters)

    @staticmethod
    def _append_uncompressed(params: list[EncodableT], uncompressed: bool | None):
        """Append UNCOMPRESSED tag to params."""
        if uncompressed:
            params.extend(["ENCODING", "UNCOMPRESSED"])

    @staticmethod
    def _append_with_labels(
        params: list[EncodableT],
        with_labels: bool | None,
        select_labels: list[str] | None,
    ):
        """Append labels behavior to params."""
        if with_labels and select_labels:
            raise DataError(
                "with_labels and select_labels cannot be provided together."
            )

        if with_labels:
            params.extend(["WITHLABELS"])
        if select_labels:
            params.extend(["SELECTED_LABELS", *select_labels])

    @staticmethod
    def _append_groupby_reduce(
        params: list[EncodableT], groupby: str | None, reduce: str | None
    ):
        """Append GROUPBY REDUCE property to params."""
        if groupby is not None and reduce is not None:
            params.extend(["GROUPBY", groupby, "REDUCE", reduce.upper()])

    @staticmethod
    def _append_retention(params: list[EncodableT], retention: int | None):

View on GitHub (pinned to da03cdc7e8)

Solutions

  1. Use select_labels alone to return a subset: with_labels=False, select_labels=['region'].
  2. Use with_labels=True alone to return all labels: drop select_labels.
  3. If assembling options dynamically, enforce mutual exclusion before the call.

Example fix

// before
client.ts().mrange('-', '+', filters=f, with_labels=True, select_labels=['region'])
// after
client.ts().mrange('-', '+', filters=f, with_labels=False, select_labels=['region'])
Defensive patterns

Strategy: validation

Validate before calling

def normalize_labels(with_labels, select_labels):
    if with_labels and select_labels:
        return False, select_labels  # prefer the subset
    return with_labels, select_labels

Type guard

def labels_compatible(with_labels, select_labels) -> bool:
    return not (with_labels and select_labels)

Try / catch

try:
    client.ts().mrange('-', '+', filters=f, with_labels=wl, select_labels=sl)
except Exception as e:
    if 'cannot be provided together' in str(e):
        client.ts().mrange('-', '+', filters=f, select_labels=sl)
    else:
        raise

Prevention

When it happens

Trigger: client.ts().mrange('-', '+', filters=f, with_labels=True, select_labels=['region']).

Common situations: Enabling WITHLABELS globally via config while also passing a select_labels list for a specific call; merging option dicts that each set one of the two; upgrading code that used select_labels and then turned on with_labels.

Related errors


AI-assisted analysis of redis/redis-py@da03cdc7e8 (2026-08-04). Data as JSON: /data/errors/de57d97eb7c59190.json. Report an issue: GitHub.