# Paused runs with union-typed user input now save and resume

> An Agno tool marked requires_user_input with a parameter typed int | None now writes its paused run to the database, so agent.continue_run(run_id=...) finds the run and completes the tool call.

- Published: 2026-10-22
- Author: ShaoLOWu
- Categories: Changelog
- Canonical: https://www.agno.com/blog/paused-runs-with-union-typed-user-input-now-save-and-resume
- Markdown: https://www.agno.com/blog/paused-runs-with-union-typed-user-input-now-save-and-resume.md

Agno's `UserInputField.to_dict()` now writes a `requires_user_input` parameter typed as a PEP 604 union, such as `quantity: int | None`, as the string `"int | None"`. The method used to read the type's `__name__`, which a union lacks, and it runs while Agno saves a paused run, so the save is what broke.

The old failure was quiet. The run paused and the caller got a normal `RunOutput` with status `paused`. The database write raised, Agno logged a warning, and the run never reached the runs table, so resuming by ID raised `RunNotFoundError`.

We ran the same script on both releases with a SQLite database and a scripted stand-in model, copied from the release's own test, that calls the tool once and then replies:

```python
@tool(requires_user_input=True, user_input_fields=["quantity"])
def place_order(item: str, quantity: int | None = None) -> str:
    return f"Ordered {quantity} x {item}"

agent = Agent(
    model=ScriptedModel(...),  # stand-in: calls place_order(item="widget"), then says "Order placed."
    tools=[place_order],
    db=SqliteDb(db_file="orders.db"),
)
paused = agent.run("Order a widget.", session_id="orders")
# The caller fills quantity = 3 on paused.active_requirements, then resumes by ID
resumed = agent.continue_run(run_id=paused.run_id, session_id="orders", requirements=paused.requirements)
```

```text
# Before (real output)
WARNING Error upserting run into db: 'types.UnionType' object has no attribute '__name__'
status: RunStatus.paused
saved in db: False
RunNotFoundError: No runs found for run ID c07d5283-2a5f-4de2-bab4-666bb613058b

# Now (real output)
status: RunStatus.paused
saved in db: True
resumed: RunStatus.completed | Ordered 3 x widget | Order placed.
```

The string fallback also changes the `field_type` label for parameterized types. A `list[str]` parameter now reads `"list[str]"` and `Optional[int]` reads `"typing.Optional[int]"`. The label is descriptive only, and the resumed tool call takes the value the caller supplied.

See the [cookbook](https://github.com/agno-agi/agno/blob/main/cookbook/02_agents/10_human_in_the_loop/user_input_required.py), and learn more about [UserInputField](https://docs.agno.com/hitl/user-input#understanding-userinputfield) in the documentation.
