fix(providers/standard): remove premature param value validation in HITLOperator#64108
Open
antonio-mello-ai wants to merge 2 commits intoapache:mainfrom
Open
fix(providers/standard): remove premature param value validation in HITLOperator#64108antonio-mello-ai wants to merge 2 commits intoapache:mainfrom
antonio-mello-ai wants to merge 2 commits intoapache:mainfrom
Conversation
2 tasks
Contributor
|
Thank you for taking this up! |
Shrividya
reviewed
Mar 23, 2026
Contributor
Shrividya
left a comment
There was a problem hiding this comment.
Great fix, thanks for taking this on! The root cause explanation in the PR description is really clear.
…ITLOperator HITLOperator params are form fields filled by a human at runtime. Calling `self.params.validate()` in `__init__` incorrectly validates param values at DAG parse time, before any human input exists. This causes `ParamValidationError` for any param without an explicit default value, breaking DAG import. The fix removes `self.params.validate()` from `validate_params()`. Value validation (type, required fields, schema) already happens correctly in `validate_params_input()` after the human submits the form. The `_options` key check is preserved — it is a structural constraint, not a value check. Closes apache#59551 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3301678 to
d1ff14b
Compare
jason810496
reviewed
Mar 24, 2026
Member
jason810496
left a comment
There was a problem hiding this comment.
Thank you for the fix, LGTM overall.
| @@ -0,0 +1 @@ | |||
| Fix HITLOperator ``ParamValidationError`` when params lack default values at DAG import time | |||
Member
There was a problem hiding this comment.
No need to add providers/standard/newsfragments/64108.bugfix.rst, could you please remove it, thanks.
| params=params, | ||
| params=ParamsDict({"_options": 1}), | ||
| ) | ||
|
|
Member
There was a problem hiding this comment.
All the test cases make sense to me. Could you please consolidate these tests with parameterize? Thanks.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a regression introduced when
HITLOperator.validate_params()was extended to callself.params.validate(). HITL params are form fields filled by a human at runtime — validating their values at DAG parse time (__init__) causesParamValidationErrorfor any param that lacks an explicit default value, breaking DAG import.Root cause:
HITLOperator.__init__→validate_params()→self.params.validate()→Param.resolve()raisesParamValidationError("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()fromvalidate_params(). Value validation (type, schema, required fields) already happens correctly invalidate_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
After fixing
Changes
providers/standard/src/airflow/providers/standard/operators/hitl.py: removedself.params.validate()fromvalidate_params(); added a docstring clarifying why value validation is intentionally deferredproviders/standard/tests/unit/standard/operators/test_hitl.py:test_validate_paramsparametrize to individual named tests for clarityParamValidationErrorcase (wrong-type value at init) — this is no longer expected at inittest_param_without_default_does_not_raise_on_init— regression test for Regression: DAG import fails with HITLOperator when params have no explicit default (ParamValidationError) #59551test_param_with_default_does_not_raise_on_init— happy pathtest_param_with_wrong_value_type_does_not_raise_on_init— confirms value validation is deferredCloses #59551
^ Add meaningful description above
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.rstor{issue_number}.significant.rst, in airflow-core/newsfragments.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 causedParamValidationErrorat 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.