Skip to content

Raise TypeError for async validators under the sync Driver - #1764

Open
digit50 wants to merge 1 commit into
apache:mainfrom
digit50:fix/sync-driver-async-validator-typeerror
Open

digit50 wants to merge 1 commit into
apache:mainfrom
digit50:fix/sync-driver-async-validator-typeerror

Conversation

@digit50

@digit50 digit50 commented Oct 15, 2026

Copy link
Copy Markdown

closes #1759

An AsyncDataValidator used with the synchronous Driver failed with AttributeError: 'coroutine' object has no attribute 'passes' and a "coroutine was never awaited" warning, instead of the TypeError the data quality docs describe. The async validator gets an async def wrapper node, the sync driver stores its unawaited coroutine as the node result, and final_node_callable handed that coroutine to act_warn / act_fail_bulk.

Changes

  • hamilton/function_modifiers/validation.py: in final_node_callable, if a validator node's result is a coroutine, close it and raise TypeError naming the validator and saying to use AsyncDriver (same message as the existing guard in the sync wrapper). The async wrapper and the AsyncDriver path are unchanged, since under AsyncDriver the result is already awaited before it reaches the final node.

How I tested this

  • Added test_sync_driver_with_async_validator_raises_type_error in tests/function_modifiers/test_validation.py, parametrized over importance="warn" and "fail". It builds a sync Driver over a node decorated with @check_output_custom(AsyncSampleDataValidator(...)), asserts execute raises TypeError mentioning AsyncDriver, and asserts no "never awaited" RuntimeWarning is emitted. Both cases failed with the AttributeError before the change and pass after it.
  • pytest tests/function_modifiers tests/plugins/test_polars*.py: everything that passed before still passes. The polars plugin tests that fail locally fail the same way without this change (polars 2.0 removed arguments they use, and xlsxwriter is not installed).
  • ruff check and ruff format --check on the changed files are clean.

Notes

If a node has several async validators, only the first coroutine is closed before the error is raised; the others can still produce a "never awaited" warning when collected. The error raised is the same either way.

Checklist

  • PR has an informative and human-readable title (this will be pulled into the release notes)
  • Changes are limited to a single goal (no scope creep)
  • Code passed the pre-commit check & code is left cleaner/nicer than when first encountered.
  • Any change in functionality is tested
  • New functions are documented (with a description, list of inputs, and expected output)
  • Placeholder code is flagged / future TODOs are captured in comments
  • Project documentation has been updated if adding/changing functionality.

Under the sync Driver an AsyncDataValidator's wrapper node returns an unawaited coroutine, and the final validation node passed it to act_warn or act_fail_bulk, which failed with AttributeError on .passes. The final node now closes such a coroutine and raises the documented TypeError naming the validator and pointing to AsyncDriver.

Closes apache#1759

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AsyncDataValidator under the sync Driver raises AttributeError, not TypeError

1 participant