antonio-mello-ai opened a new pull request, #64108: URL: https://github.com/apache/airflow/pull/64108
<!-- Thank you for contributing! Please make sure that your code changes are covered with tests. And in case of a new feature or fix, tell us about it, write a summary of changes. In case of a bug fix, tell us the expected behavior and the error message. Please also check the Contributing guide: https://github.com/apache/airflow/blob/main/contributing-docs/README.rst Read the Pull Request Guidelines for more information. In case of fundamental code changes, an Airflow Improvement Proposal (AIP) is needed. In case of a new dependency, check compliance with the ASF 3rd Party License Policy. In case of backwards incompatible changes please leave a note in a newsfragment file, named `{pr_number}.significant.rst` or `{issue_number}.significant.rst`, in airflow-core/newsfragments --> ### Summary Fixes a regression introduced when `HITLOperator.validate_params()` was extended to call `self.params.validate()`. HITL params are **form fields filled by a human at runtime** — validating their values at DAG parse time (`__init__`) causes `ParamValidationError` for any param that lacks an explicit default value, breaking DAG import. **Root cause**: `HITLOperator.__init__` → `validate_params()` → `self.params.validate()` → `Param.resolve()` raises `ParamValidationError("No value passed and Param has no default value")` if the param has no default. This validation runs at parse time, but no human input exists yet at that point. **Fix**: Remove `self.params.validate()` from `validate_params()`. Value validation (type, schema, required fields) already happens correctly in `validate_params_input()` after the human submits the form. The `"_options"` key check is preserved — it is a structural constraint that can and should be validated at init time. Credit to @henry3260 who identified the same fix in #59653, which closed as stale without a review. ### Before fixing ```python # DAG import fails with: # ParamValidationError: Invalid input for param my_param: No value passed and Param has no default value HITLOperator( task_id="ask_user", subject="Please provide input", options=["OK"], params={"my_param": Param(type="string")}, # no default — valid HITL use case ) ``` ### After fixing ```python # DAG imports successfully. Value is validated when the human submits the form. HITLOperator( task_id="ask_user", subject="Please provide input", options=["OK"], params={"my_param": Param(type="string")}, ) ``` ### Changes - `providers/standard/src/airflow/providers/standard/operators/hitl.py`: removed `self.params.validate()` from `validate_params()`; added a docstring clarifying why value validation is intentionally deferred - `providers/standard/tests/unit/standard/operators/test_hitl.py`: - Renamed `test_validate_params` parametrize to individual named tests for clarity - Removed the `ParamValidationError` case (wrong-type value at init) — this is no longer expected at init - Added `test_param_without_default_does_not_raise_on_init` — regression test for #59551 - Added `test_param_with_default_does_not_raise_on_init` — happy path - Added `test_param_with_wrong_value_type_does_not_raise_on_init` — confirms value validation is deferred Closes #59551 --- **^ Add meaningful description above** Read the **[Pull Request Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)** for more information. In case of fundamental code changes, an Airflow Improvement Proposal ([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals)) is needed. In case of a new dependency, check compliance with the [ASF 3rd Party License Policy](https://www.apache.org/legal/resolved.html#category-x). In case of backwards incompatible changes please leave a note in a newsfragment file, named `{pr_number}.significant.rst` or `{issue_number}.significant.rst`, in [airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments). <!-- Please keep an empty line above the dashes. --> **Are there any user-facing changes?** Yes — DAGs using `HITLOperator` (or any subclass) with params that have no explicit default value will now import successfully, as they should. **Are there any breaking changes?** No. The removed call `self.params.validate()` was incorrect behavior — it caused `ParamValidationError` at DAG parse time. Removing it restores correct behavior without impacting any valid use case. **Commit message for squash merge:** fix(providers/standard): remove premature param value validation in HITLOperator **Generated with AI assistance**: Implemented with Claude Code. The logic, root cause analysis, and test strategy were reviewed and confirmed correct. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
