Skip to content

fix: guard None text in text_message_output and add output guardrail count to RunErrorDetails#3377

Closed
zhoufengen wants to merge 1 commit into
openai:mainfrom
zhoufengen:fix/text-message-output-none-and-error-details-guardrail
Closed

fix: guard None text in text_message_output and add output guardrail count to RunErrorDetails#3377
zhoufengen wants to merge 1 commit into
openai:mainfrom
zhoufengen:fix/text-message-output-none-and-error-details-guardrail

Conversation

@zhoufengen
Copy link
Copy Markdown
Contributor

Summary

Two small, related fixes in the SDK's output-handling utilities:

1. ItemHelpers.text_message_output — guard against None text

extract_text (the sibling method in the same class) already applies an or "" guard with an explicit comment explaining that provider gateways (e.g. LiteLLM) and model_construct paths during streaming can surface None for ResponseOutputText.text. text_message_output had the same concatenation loop without the guard, so the same TypeError: can only concatenate str (not "NoneType") to str could fire through text_message_outputs and agent.py's text_output path.

Fix: text += item.text or ""

2. pretty_print_run_error_details — include output guardrail count

pretty_print_result and pretty_print_run_result_streaming both report input_guardrail_results and output_guardrail_results. pretty_print_run_error_details reported only the input count, so RunErrorDetails.__str__() silently omitted output guardrail results — misleading when an output guardrail is the reason the run failed.

Fix: add the missing output_guardrail_results line.

Test plan

New file tests/utils/test_pretty_print_and_items.py (5 tests):

  • test_text_message_output_returns_empty_string_for_none_text — reproduces the TypeError on the old code via model_construct
  • test_text_message_output_returns_text_normally — normal path still works
  • test_text_message_outputs_handles_none_text_across_items — multi-item list with a None entry
  • test_pretty_print_run_error_details_includes_output_guardrail_count — asserts both counts appear
  • test_pretty_print_run_error_details_zero_output_guardrails — zero case

Updated inline snapshot in tests/test_pretty_print.py::test_pretty_run_error_details.

uv run pytest tests/utils/test_pretty_print_and_items.py tests/test_pretty_print.py -v

tests pass

Full verification stack:

  • make format — no changes
  • make lint — all checks passed
  • make typecheck — mypy: no issues (767 files), pyright: 0 errors
  • make tests (parallel + serial) — all passed

Issue number

N/A (no existing issue; both are small, self-contained defects).

Checks

  • I've added new tests (if relevant)
  • I've added/updated the relevant documentation
  • I've run make lint and make format
  • I've made sure tests pass

…ardrail count to RunErrorDetails pretty-print

- ItemHelpers.text_message_output: apply the same `or ""` guard that
  extract_text already uses. Provider gateways (e.g. LiteLLM) and
  model_construct paths during streaming can surface None for
  ResponseOutputText.text; without the guard the concatenation raises
  TypeError.

- pretty_print_run_error_details: add the missing output_guardrail_results
  line so RunErrorDetails.__str__ is consistent with pretty_print_result
  and pretty_print_run_result_streaming, which both report both guardrail
  counts.

- Add tests/utils/test_pretty_print_and_items.py covering both fixes.
- Update the existing inline snapshot in tests/test_pretty_print.py.
@seratch seratch added duplicate This issue or pull request already exists labels May 12, 2026
@seratch seratch closed this May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

duplicate This issue or pull request already exists

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants