Skip to content

Fix crossed-bound XCom slices returning wrong rows via negative SQL L…#69273

Open
bramhanandlingala wants to merge 1 commit into
apache:mainfrom
bramhanandlingala:fix/#69204
Open

Fix crossed-bound XCom slices returning wrong rows via negative SQL L…#69273
bramhanandlingala wants to merge 1 commit into
apache:mainfrom
bramhanandlingala:fix/#69204

Conversation

@bramhanandlingala

@bramhanandlingala bramhanandlingala commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the XCom sequence-slice endpoint (get_mapped_xcom_by_slice) returning incorrect rows — or erroring, depending on the database backend — when a requested slice has crossed bounds (i.e. the effective stop comes before the effective start, which Python evaluates as an empty result).

Root cause

The endpoint maps Python slice semantics onto SQLAlchemy's Query.slice(low, high), which compiles to:

OFFSET low
LIMIT (high - low)

When high <= low, this produces a negative LIMIT, which SQLAlchemy does not clamp:

  • SQLite treats a negative LIMIT as "no limit" and silently returns the wrong (extra) rows instead of an empty result.
  • PostgreSQL / MySQL reject the query outright, since LIMIT cannot be negative.

This affects 4 of the branches in get_mapped_xcom_by_slice — specifically where both start and stop are provided and a COUNT query is needed to resolve a mixed-sign bound (e.g. start=2, stop=-3), since that's where a crossed slice can occur without either individual bound being invalid on its own.

Fix

Added a small helper, _sliced_or_empty(), that checks for crossed bounds before calling .slice() and returns .limit(0) instead:

def _sliced_or_empty(query: Select, low: int, high: int) -> Select:
    if high <= low:
        return query.limit(0)
    return query.slice(low, high)

Replaced the 4 affected query.slice(...) calls with _sliced_or_empty(query, ...). No other logic changes — non-crossed slices behave exactly as before.

Files changed

  • airflow-core/src/airflow/api_fastapi/execution_api/routes/xcoms.py
  • airflow-core/tests/unit/api_fastapi/execution_api/versions/head/test_xcoms.py

Testing

Added tests covering all 4 previously-affected branches, verified against real Python slice semantics.

Fixes #69204

Gen-AI disclosure: I used a generative AI tool to help identify the root
cause, write tests, and draft the PR description. I reviewed, tested, and
verified all changes locally before submitting.

Was generative AI tooling used to co-author this PR?
  • Yes — Claude

Generated-by: Claude following the guidelines

@boring-cyborg boring-cyborg Bot added area:API Airflow's REST/HTTP API area:task-sdk labels Jul 2, 2026
@potiuk potiuk added the ready for maintainer review Set after triaging when all criteria pass. label Jul 8, 2026
@shahar1 shahar1 removed the ready for maintainer review Set after triaging when all criteria pass. label Jul 25, 2026

@shahar1 shahar1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:API Airflow's REST/HTTP API area:task-sdk

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug/XCom sequence slice endpoint returns wrong rows for crossed-bound slices (negative SQL LIMIT)

3 participants