apache/beam · error · SplitNotPossibleError

Query cannot have any sort orders.

Error message

Query cannot have any sort orders.

What it means

validate_split rejects queries that carry sort orders, because scatter-based splitting relies on key ranges; adding an order (especially non-__key__ order) makes split boundaries inconsistent with the query semantics, so SplitNotPossibleError is raised when query.order is non-empty.

Source

Thrown at sdks/python/apache_beam/io/gcp/datastore/v1new/query_splitter.py:98

    last_client_key = next_client_key

  splits.append(_create_split(last_client_key, None, query))
  return splits


def validate_split(query):
  """
  Verifies that the given query can be properly scattered.

  Note that equality and ancestor filters are allowed, however they may result
  in inefficient sharding.

  Raises:
    QuerySplitterError if split could not be performed owing to query
      parameters.
  """
  if query.order:
    raise SplitNotPossibleError('Query cannot have any sort orders.')

  if query.limit is not None:
    raise SplitNotPossibleError('Query cannot have a limit set.')

  for filter in query.filters:
    if isinstance(filter[1], ValueProvider):
      filter_operator = filter[1].get()
    else:
      filter_operator = filter[1]
    if filter_operator in ['<', '<=', '>', '>=']:
      raise SplitNotPossibleError('Query cannot have any inequality filters.')


def _create_scatter_query(query, num_splits):
  """Creates a scatter query from the given user query."""
  # There is a split containing entities before and after each scatter entity:
  # ||---*------*------*------*------*------*------*---||  * = scatter entity
  # If we represent each split as a region before a scatter entity, there is an

View on GitHub (pinned to 12126d8942)

Solutions

  1. Remove query.order before splitting (build a separate un-ordered query for the split path).
  2. Split on the default key ordering; apply ordering only after results are fetched if needed.
  3. Catch SplitNotPossibleError and fall back to a single unsplit query run.
  4. If ordering is essential, implement manual range filtering instead of scatter-based splitting.

Example fix

// before
query.order = ['timestamp']
splits = query_splitter.get_splits(client, query, n)
// after
query.order = []  # or omit ordering entirely
splits = query_splitter.get_splits(client, query, n)
Defensive patterns

Strategy: validation

Validate before calling

if query.order:
    raise ValueError('clear query.order before splitting')
splits = query_splitter.get_splits(client, query, n)

Type guard

def is_splittable_query(query):
    return not query.order and query.limit is None

Try / catch

try:
    splits = query_splitter.get_splits(client, query, n)
except SplitNotPossibleError:
    logging.warning('query has sort orders; falling back to unsplit query')
    splits = [query]

Prevention

When it happens

Trigger: Calling get_splits (or validate_split) with a query whose .order list is set — e.g. query.order = ['timestamp'] or any property ordering added before splitting.

Common situations: Reusing a query built for presentation/ordered reads in a splitting context; frameworks auto-adding order to dedupe results; porting a query from a normal fetch to a parallel-read pipeline.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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