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

potiuk 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 f2db94d08d1 Refactor validate_key to raise ValueError instead of 
AirflowException (#68890)
f2db94d08d1 is described below

commit f2db94d08d13607ec58edf82ad0e54c0f2e44bd1
Author: Taehoon Kim <[email protected]>
AuthorDate: Mon Aug 31 03:00:52 2026 +0900

    Refactor validate_key to raise ValueError instead of AirflowException 
(#68890)
    
    * Replace AirflowException with ValueError in validate_key
    
    * Update Kubernetes tests and known exceptions for refactor
    
    * Fix backwards compatibility in Kubernetes tests for validate_key
    
    * Align validate_key error message with Task SDK
    
    * Add newsfragment for KubernetesPodOperator behavior change
---
 airflow-core/newsfragments/68890.significant.rst              |  6 ++++++
 airflow-core/src/airflow/utils/helpers.py                     | 10 ++++------
 airflow-core/tests/unit/utils/test_helpers.py                 | 11 +++++------
 generated/known_airflow_exceptions.txt                        |  2 +-
 .../tests/kubernetes_tests/test_kubernetes_pod_operator.py    |  2 +-
 .../tests/unit/cncf/kubernetes/operators/test_pod.py          |  2 +-
 6 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/airflow-core/newsfragments/68890.significant.rst 
b/airflow-core/newsfragments/68890.significant.rst
new file mode 100644
index 00000000000..0dc77788cc7
--- /dev/null
+++ b/airflow-core/newsfragments/68890.significant.rst
@@ -0,0 +1,6 @@
+The ``airflow.utils.helpers.validate_key`` utility function now raises a 
``ValueError`` instead of an ``AirflowException`` when an invalid key is 
provided (such as an invalid format or length limit violation).
+
+This change aligns the core function with the Task SDK's ``validate_key`` 
behavior.
+
+**Breaking Change for KubernetesPodOperator Users:**
+Because ``validate_key`` is used internally by the ``KubernetesPodOperator`` 
to validate pod names, any DAGs that wrap ``KubernetesPodOperator`` execution 
in an ``except AirflowException`` block to catch invalid pod names will no 
longer catch this error. You must update your exception handling to catch 
``ValueError`` instead.
diff --git a/airflow-core/src/airflow/utils/helpers.py 
b/airflow-core/src/airflow/utils/helpers.py
index 73265463edc..d6463faea19 100644
--- a/airflow-core/src/airflow/utils/helpers.py
+++ b/airflow-core/src/airflow/utils/helpers.py
@@ -54,17 +54,15 @@ def validate_key(k: str, max_length: int = 250):
     """Validate value used as a key."""
     if not isinstance(k, str):
         raise TypeError(f"The key has to be a string and is {type(k)}:{k}")
-    if len(k) > max_length:
-        raise AirflowException(f"The key: {k} has to be less than {max_length} 
characters")
+    if (length := len(k)) > max_length:
+        raise ValueError(f"The key has to be less than {max_length} 
characters, not {length}")
     if not KEY_REGEX.match(k):
-        raise AirflowException(
+        raise ValueError(
             f"The key {k!r} has to be made of alphanumeric characters, dashes, 
"
             f"dots and underscores exclusively"
         )
     if ".." in k and not conf.getboolean("core", "allow_double_dot_in_ids", 
fallback=False):
-        raise AirflowException(
-            f"The key {k!r} must not contain consecutive dots ('..') to 
prevent path traversal"
-        )
+        raise ValueError(f"The key {k!r} must not contain consecutive dots 
('..') to prevent path traversal")
 
 
 def ask_yesno(question: str, default: bool | None = None, output_fn=print) -> 
bool:
diff --git a/airflow-core/tests/unit/utils/test_helpers.py 
b/airflow-core/tests/unit/utils/test_helpers.py
index ab82f820475..944abd48c93 100644
--- a/airflow-core/tests/unit/utils/test_helpers.py
+++ b/airflow-core/tests/unit/utils/test_helpers.py
@@ -23,7 +23,6 @@ from typing import TYPE_CHECKING
 
 import pytest
 
-from airflow.exceptions import AirflowException
 from airflow.jobs.base_job_runner import BaseJobRunner
 from airflow.serialization.definitions.notset import NOTSET
 from airflow.utils import helpers
@@ -131,24 +130,24 @@ class TestHelpers:
                 "key with space",
                 "The key 'key with space' has to be made of alphanumeric "
                 "characters, dashes, dots and underscores exclusively",
-                AirflowException,
+                ValueError,
             ),
             (
                 "key_with_!",
                 "The key 'key_with_!' has to be made of alphanumeric "
                 "characters, dashes, dots and underscores exclusively",
-                AirflowException,
+                ValueError,
             ),
-            (" " * 251, f"The key: {' ' * 251} has to be less than 250 
characters", AirflowException),
+            (" " * 251, "The key has to be less than 250 characters, not 251", 
ValueError),
             (
                 "my..key",
                 "The key 'my..key' must not contain consecutive dots ('..') to 
prevent path traversal",
-                AirflowException,
+                ValueError,
             ),
             (
                 "..",
                 "The key '..' must not contain consecutive dots ('..') to 
prevent path traversal",
-                AirflowException,
+                ValueError,
             ),
         ],
     )
diff --git a/generated/known_airflow_exceptions.txt 
b/generated/known_airflow_exceptions.txt
index 97aab5bce79..bfb87136d2e 100644
--- a/generated/known_airflow_exceptions.txt
+++ b/generated/known_airflow_exceptions.txt
@@ -21,7 +21,7 @@ airflow-core/src/airflow/utils/db.py::1
 airflow-core/src/airflow/utils/db_cleanup.py::1
 airflow-core/src/airflow/utils/db_manager.py::3
 airflow-core/src/airflow/utils/dot_renderer.py::3
-airflow-core/src/airflow/utils/helpers.py::4
+airflow-core/src/airflow/utils/helpers.py::1
 airflow-core/src/airflow/utils/process_utils.py::1
 airflow-core/tests/unit/models/test_dag.py::1
 airflow-core/tests/unit/models/test_taskinstance.py::3
diff --git 
a/kubernetes-tests/tests/kubernetes_tests/test_kubernetes_pod_operator.py 
b/kubernetes-tests/tests/kubernetes_tests/test_kubernetes_pod_operator.py
index bd14e9a4a61..33c1cebcdfb 100644
--- a/kubernetes-tests/tests/kubernetes_tests/test_kubernetes_pod_operator.py
+++ b/kubernetes-tests/tests/kubernetes_tests/test_kubernetes_pod_operator.py
@@ -1113,7 +1113,7 @@ class TestKubernetesPodOperatorSystem:
         # Name is now in template fields, and it's final value requires context
         # so we need to execute for name validation
         context = create_context(k)
-        with pytest.raises(AirflowException):
+        with pytest.raises((ValueError, AirflowException), match="has to be"):
             k.execute(context)
 
     def test_on_kill(self):
diff --git 
a/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/operators/test_pod.py 
b/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/operators/test_pod.py
index d259d87c623..15a37133c3e 100644
--- a/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/operators/test_pod.py
+++ b/providers/cncf/kubernetes/tests/unit/cncf/kubernetes/operators/test_pod.py
@@ -1659,7 +1659,7 @@ class TestKubernetesPodOperator:
             task_id="task",
         )
 
-        with pytest.raises(AirflowException):
+        with pytest.raises((ValueError, AirflowException), match="has to be"):
             self.run_pod(k)
 
     def test_create_with_affinity(self):

Reply via email to