apache/beam · error · TypeError

: filters must be a sequence of tuple with length=3 got %r…

Error message

%s: filters must be a sequence of tuple with length=3 got %r instead

What it means

When converting a Beam Query for the Cloud Datastore v1 client, each filter must be a 3-tuple (property, operator, value). _set_runtime_filters checks every tuple has length exactly 3 and raises TypeError otherwise, because a malformed filter cannot be mapped onto the structured-query proto.

Solutions

  1. Ensure every entry in query.filters is a (property, operator, value) 3-tuple.
  2. If the value is missing, supply it or use an operator form that takes one, e.g. ('age', '>', 0).
  3. When using templates, each element may be a ValueProvider, but the tuple itself must still have exactly three ValueProvider/str elements.
  4. Validate filters at pipeline-construction time with a small assertion loop before creating the Query.

Example fix

// before
query = Query(kind='Person', filters=[('age', '>')])
// after
query = Query(kind='Person', filters=[('age', '>', 30)])
Defensive patterns

Strategy: validation

Validate before calling

def check_filters(filters):
    for f in filters:
        if not (isinstance(f, tuple) and len(f) == 3):
            raise TypeError(f'Filter must be (prop, op, value) 3-tuple, got {f!r}')

Try / catch

try:
    client_query = query._to_client_query()
except TypeError as e:
    raise PipelineError(f'Malformed Datastore filters: {e}') from e

Prevention

When it happens

Trigger: Building Query(..., filters=[...]) with a tuple of length 1, 2, or 4 (e.g. forgetting the value: ('age', '>')), passing a non-iterable filter, or appending filters of the wrong shape at runtime via _to_client_query.

Common situations: Migrating from other Datastore client libraries where filters are method calls (add_filter(prop, op, value)) rather than tuples; developers port code and pass 2-tuples, or build filters dynamically and accidentally drop an element.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/96b64dd2ed6ab7dc. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/io/gcp/datastore/v1new/types.py:120

        kind=self.kind,
        project=self.project,
        namespace=self.namespace,
        ancestor=ancestor_client_key,
        filters=self.filters,
        projection=self.projection,
        order=self.order,
        distinct_on=self.distinct_on)

  def _set_runtime_filters(self):
    """
    Extracts values from ValueProviders in `self.filters` if available
    :param filters: sequence of tuple[str, str, str] or
    sequence of tuple[ValueProvider, ValueProvider, ValueProvider]
    :return: tuple[str, str, str]
    """
    runtime_filters = []
    if not all(len(filter_tuple) == 3 for filter_tuple in self.filters):
      raise TypeError(
          '%s: filters must be a sequence of tuple with length=3'
          ' got %r instead' % (self.__class__.__name__, self.filters))

    for filter_type, filter_operator, filter_value in self.filters:
      if isinstance(filter_type, ValueProvider):
        filter_type = filter_type.get()
      if isinstance(filter_operator, ValueProvider):
        filter_operator = filter_operator.get()
      if isinstance(filter_value, ValueProvider):
        filter_value = filter_value.get()
      runtime_filters.append((filter_type, filter_operator, filter_value))

    return runtime_filters or ()

  def clone(self):
    return copy.copy(self)

  def __repr__(self):

View on GitHub (pinned to 12126d8942)