This is an automated email from the ASF dual-hosted git repository.

shahar1 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new c5bbd4b087a Instruct agents to reduce direct AirflowException usage 
(#68656)
c5bbd4b087a is described below

commit c5bbd4b087a7691f650076e03fdce503124aa628
Author: Shahar Epstein <[email protected]>
AuthorDate: Wed Jun 17 11:30:57 2026 +0300

    Instruct agents to reduce direct AirflowException usage (#68656)
    
    Make explicit on both the authoring and review sides that direct
    AirflowException raises are being reduced, not added. New direct usages
    are disallowed (already enforced by the check-no-new-airflow-exceptions
    prek hook), and the reviewer guidance clarifies that the only acceptable
    movement of an AirflowException line is relocating an already-existing
    one verbatim during a refactor, which is not a new usage.
    
    Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
---
 .github/instructions/code-review.instructions.md | 2 +-
 AGENTS.md                                        | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/instructions/code-review.instructions.md 
b/.github/instructions/code-review.instructions.md
index 08eec81085d..da2674c4c1a 100644
--- a/.github/instructions/code-review.instructions.md
+++ b/.github/instructions/code-review.instructions.md
@@ -32,7 +32,7 @@ Use these rules when reviewing pull requests to the Apache 
Airflow repository.
 - **Flag any `@lru_cache(maxsize=None)`.** This creates an unbounded cache — 
every unique argument set is cached forever. Note: `@lru_cache()` without 
arguments defaults to `maxsize=128` and is fine.
 - **Flag any heavy import** (e.g., `kubernetes.client`) in multi-process code 
paths that is not behind a `TYPE_CHECKING` guard.
 - **Flag any file, connection, or session opened without a context manager or 
`try/finally`.**
-- **Flag any new `raise AirflowException` usage.** The community has stopped 
adding new ones (enforced by the `check-no-new-airflow-exceptions` prek hook) — 
prefer Python's standard exceptions (`ValueError`, `TypeError`, `OSError`), or 
a dedicated class in the appropriate `exceptions.py`. **Do not suggest changing 
specific exceptions back to `AirflowException`.**
+- **Flag any new `raise AirflowException` usage.** The community is reducing 
direct `AirflowException` usage, not increasing it; new ones are not allowed 
(enforced by the `check-no-new-airflow-exceptions` prek hook) — prefer Python's 
standard exceptions (`ValueError`, `TypeError`, `OSError`), or a dedicated 
class in the appropriate `exceptions.py`. **The one exception is a pure 
relocation: an already-existing `AirflowException` moved verbatim during a 
refactor (e.g. code moved between fi [...]
 
 ## Testing Requirements
 
diff --git a/AGENTS.md b/AGENTS.md
index 4f8b4a37d44..f0eb03813f4 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -139,7 +139,7 @@ reported as such are described in "What is NOT considered a 
security vulnerabili
 - In `airflow-core`, functions with a `session` parameter must not call 
`session.commit()`. Use keyword-only `session` parameters.
 - Imports at top of file. Valid exceptions: circular imports, lazy loading for 
worker isolation, `TYPE_CHECKING` blocks.
 - Guard heavy type-only imports (e.g., `kubernetes.client`) with 
`TYPE_CHECKING` in multi-process code paths.
-- Define dedicated exception classes or use existing exceptions such as 
`ValueError` instead of raising the broad `AirflowException` directly. Each 
error case should have a specific exception type that conveys what went wrong.
+- Define dedicated exception classes or use existing exceptions such as 
`ValueError` instead of raising the broad `AirflowException` directly. Each 
error case should have a specific exception type that conveys what went wrong. 
**Never add new direct `raise AirflowException(...)` usages — the community is 
actively reducing them, not adding more, and the 
`check-no-new-airflow-exceptions` prek hook enforces this across 
`airflow-core`, `airflow-ctl`, `task-sdk`, `providers`, and `shared`.**  [...]
 - Translate domain-layer exceptions to `HTTPException` at FastAPI route 
boundaries. In `airflow-core/src/airflow/core_api/` route handlers, catch 
errors raised by domain code (e.g., `ValueError` from 
`airflow.state.metastore.MetastoreStateBackend` for a missing row or invalid 
input) and re-raise as `HTTPException` with the right status (`404` for 
not-found, `400` for invalid input). Otherwise they propagate as `500 Internal 
Server Error`, leaking internals and misleading clients.
 - Bulk `DELETE`/`UPDATE` in the scheduler loop or any synchronous interval 
task (e.g. `call_regular_interval` callbacks) must be batched with `LIMIT` and 
committed between batches — never issue a single unbounded bulk write against a 
user-driven table. Unbounded bulk writes hold row locks for the entire 
transaction (blocking concurrent writers) and stall the scheduler main loop. 
Filter columns used by the cleanup must be indexed. Follow the batching pattern 
in `airflow-core/src/airflow/u [...]
 - Name functions and methods with action verbs: `get_`, `extract_`, `find_`, 
`compute_`, `build_`, etc. Avoid noun-only names like `_serialize_keys` or 
`_base_names` — they read as attributes, not callables. Predicates (`is_`, 
`has_`) are the one exception.

Reply via email to