{"record":{"id":"d0bd048b3f76149e","repo":"apache/beam","slug":"query-cannot-have-any-sort-orders","errorCode":null,"errorMessage":"Query cannot have any sort orders.","messagePattern":"Query cannot have any sort orders\\.","errorType":"exception","errorClass":"SplitNotPossibleError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/io/gcp/datastore/v1new/query_splitter.py","lineNumber":98,"sourceCode":"    last_client_key = next_client_key\n\n  splits.append(_create_split(last_client_key, None, query))\n  return splits\n\n\ndef validate_split(query):\n  \"\"\"\n  Verifies that the given query can be properly scattered.\n\n  Note that equality and ancestor filters are allowed, however they may result\n  in inefficient sharding.\n\n  Raises:\n    QuerySplitterError if split could not be performed owing to query\n      parameters.\n  \"\"\"\n  if query.order:\n    raise SplitNotPossibleError('Query cannot have any sort orders.')\n\n  if query.limit is not None:\n    raise SplitNotPossibleError('Query cannot have a limit set.')\n\n  for filter in query.filters:\n    if isinstance(filter[1], ValueProvider):\n      filter_operator = filter[1].get()\n    else:\n      filter_operator = filter[1]\n    if filter_operator in ['<', '<=', '>', '>=']:\n      raise SplitNotPossibleError('Query cannot have any inequality filters.')\n\n\ndef _create_scatter_query(query, num_splits):\n  \"\"\"Creates a scatter query from the given user query.\"\"\"\n  # There is a split containing entities before and after each scatter entity:\n  # ||---*------*------*------*------*------*------*---||  * = scatter entity\n  # If we represent each split as a region before a scatter entity, there is an","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/io/gcp/datastore/v1new/query_splitter.py#L80-L116","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Remove query.order before splitting (build a separate un-ordered query for the split path).","Split on the default key ordering; apply ordering only after results are fetched if needed.","Catch SplitNotPossibleError and fall back to a single unsplit query run.","If ordering is essential, implement manual range filtering instead of scatter-based splitting."],"exampleFix":"// before\nquery.order = ['timestamp']\nsplits = query_splitter.get_splits(client, query, n)\n// after\nquery.order = []  # or omit ordering entirely\nsplits = query_splitter.get_splits(client, query, n)","handlingStrategy":"validation","validationCode":"if query.order:\n    raise ValueError('clear query.order before splitting')\nsplits = query_splitter.get_splits(client, query, n)","typeGuard":"def is_splittable_query(query):\n    return not query.order and query.limit is None","tryCatchPattern":"try:\n    splits = query_splitter.get_splits(client, query, n)\nexcept SplitNotPossibleError:\n    logging.warning('query has sort orders; falling back to unsplit query')\n    splits = [query]","preventionTips":["Keep split-path queries order-free; sort results after fetch","Build separate query objects for ordered reads vs parallel scans","Deduplicate post-fetch instead of relying on ordering in split queries","Validate with is_splittable_query before invoking get_splits"],"tags":["python","datastore","query-validation","beam-io"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}