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):