Skip to content

OutputAdapter silently coerces string output to another type when output_type is a Union including str. #12625

Description

@Anishithavaram-4242

Describe the bug
OutputAdapter.run() skips ast.literal_eval coercion when output_type is exactly str, but not when output_type is a Union that includes str (e.g. str | None, Optional[str]). A rendered value like "42" declared with output_type=str | None is silently coerced to the int 42 instead of being preserved as the string "42".

Affected code
haystack/components/converters/output_adapter.py, inside run():

with contextlib.suppress(Exception):
    if not self._unsafe and self.output_type is not str:
        output_result = ast.literal_eval(output_result)

To Reproduce

from haystack.components.converters import OutputAdapter

adapter = OutputAdapter(template="{{ reply }}", output_type=str | None)
result = adapter.run(reply="42")
# Expected: {"output": "42"}
# Actual: {"output": 42}  (coerced to int)

Context
This is the same class of bug just found and fixed in ConditionalRouter (see #12617, PR #12620), which has the identical output_type is not str pattern. I confirmed via GitHub search that no existing open issue or PR currently covers this specific OutputAdapter case before filing.

Proposed fix
Add a helper checking whether str is output_type itself or a member of a Union output_type, matching the same fix pattern used for ConditionalRouter. I have a fix and passing regression test ready.

Environment
Haystack main branch, Python 3.12.4

Activity

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

Metadata

Metadata

Assignees

Labels

P2Medium priority, add to the next sprint if no P1 available

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions