Skip to content

fix(realtime): raise UserError for input_type without on_handoff#3248

Merged
seratch merged 1 commit intoopenai:mainfrom
adityasingh2400:fix/realtime-rthandoff-audit
May 8, 2026
Merged

fix(realtime): raise UserError for input_type without on_handoff#3248
seratch merged 1 commit intoopenai:mainfrom
adityasingh2400:fix/realtime-rthandoff-audit

Conversation

@adityasingh2400
Copy link
Copy Markdown
Contributor

Summary

The validation guard at the top of `realtime_handoff()` is a tautology:

```python
assert (on_handoff and input_type) or not (on_handoff and input_type), (
"You must provide either both on_handoff and input_type, or neither"
)
```

`(X) or not (X)` is always `True`, so the assertion never fires. When a caller does `realtime_handoff(agent, input_type=int)` (input_type without on_handoff), the function falls through to a less helpful `assert callable(on_handoff)` further down, or — under `python -O` where assertions are stripped — silently constructs a `Handoff` whose `on_invoke_handoff` callable hits a confusing `TypeError: None is not a callable object` at first invocation.

This mirrors the same pattern in `agents/handoffs/init.py` line 255, but the realtime path was the only one missed when Wave 7 cleaned things up around #3243. Replace the dead assertion with an explicit `UserError` so the contract documented by the overloads (input_type only with on_handoff) is enforced uniformly, including under `-O`.

Test plan

  • `pytest tests/realtime -q` -> 233 passed
  • New test `test_realtime_handoff_input_type_requires_on_handoff` fails on main (`AssertionError` from the secondary guard) and passes after the fix (`UserError`)
  • Existing `test_realtime_handoff_invalid_param_counts_raise` still passes — same UserError surface area for arity mismatches

🤖 Generated with Claude Code

The assertion in realtime_handoff was tautological:
`(A and B) or not (A and B)` is always True. Calling
`realtime_handoff(agent, input_type=int)` would slip past it and
hit a misleading downstream AssertionError under default Python,
or silently produce a broken Handoff under `python -O`.

Replace with an explicit UserError that runs unconditionally and
matches the documented call-shape contract (the overloads only
accept input_type alongside on_handoff).
@github-actions github-actions Bot added bug Something isn't working feature:realtime labels May 8, 2026
@seratch
Copy link
Copy Markdown
Member

seratch commented May 8, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@seratch seratch added this to the 0.17.x milestone May 8, 2026
@seratch seratch merged commit 12ad112 into openai:main May 8, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working feature:realtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants