Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] "'coroutine' object has no attribute 'to_dict'." in trace_async_validator #1190

Open
SwaY2000 opened this issue Dec 9, 2024 · 2 comments
Assignees
Labels
bug Something isn't working

Comments

@SwaY2000
Copy link

SwaY2000 commented Dec 9, 2024

Describe the bug
When using the ExampleAsyncValidator with AsyncGuard in versions 0.5.4 through 0.6.0, an error occurs:
'coroutine' object has no attribute 'to_dict'.

The issue appears in the trace_async_validator method of the framework during the call:

resp = await fn(*args, **kwargs)

If resp is awaited again (resp = await resp), the error disappears, and everything works as expected. In versions up to 0.5.3 (inclusive) there was no such problem.

To Reproduce
Steps to reproduce the behavior:

RAIL Spec
Use the following custom validator:

import asyncio

from guardrails import AsyncGuard, register_validator
from guardrails.validators import Validator, ValidationResult, PassResult, FailResult


@register_validator(name="example-async-validator", data_type="string")
class ExampleAsyncValidator(Validator):
    async def validate(self, value: str, metadata: dict) -> ValidationResult:
        # Simulate async logic
        if "invalid" in value:
            return FailResult(error_message="Validation failed.")
        return PassResult(metadata={"validated": True})

async def main():
    async_guard = AsyncGuard()
    async_guard.use(ExampleAsyncValidator)

    # Validate a value
    result = await async_guard.validate("test invalid value")

asyncio.run(main())

Expected behavior
The validator should work as expected without needing to explicitly double-await the result (await resp).

Library version:
0.5.4 to 0.6.0

Additional context
The issue seems to originate from the handling of coroutines within the trace_async_validator method. Previously, the framework might have handled the asynchronous results differently, causing this regression in the later versions.

Temporary workaround:
Explicitly double-await the result in the trace_async_validator:

resp = await fn(*args, **kwargs)
resp = await resp
@SwaY2000 SwaY2000 added the bug Something isn't working label Dec 9, 2024
@zsimjee zsimjee self-assigned this Dec 9, 2024
@SwaY2000
Copy link
Author

@zsimjee Hello! Please tell me, is there anything known about this problem? Is this a problem on the framework side? If yes, please tell me, in what time frame can I expect a fix?

@CalebCourier CalebCourier self-assigned this Jan 3, 2025
@CalebCourier
Copy link
Collaborator

Hi @SwaY2000, Sorry for the delayed response. The issue here is that you are setting the validate method to an async function which does not match the parent Validator class' specification; it must by synchronous. If your validation logic is truly asynchronous, you should override async_validate instead.

Note that this would restrict ExampleAsyncValidator to only working with AsyncGuards unless you used something like nest-asyncio to also provide a synchronous validate implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants