Skip to content

fix(items): guard None refusal in ItemHelpers.extract_last_content#3750

Closed
jawwad-ali wants to merge 1 commit into
openai:mainfrom
jawwad-ali:fix/items-none-refusal
Closed

fix(items): guard None refusal in ItemHelpers.extract_last_content#3750
jawwad-ali wants to merge 1 commit into
openai:mainfrom
jawwad-ali:fix/items-none-refusal

Conversation

@jawwad-ali

Copy link
Copy Markdown
Contributor

Summary

ItemHelpers.extract_last_content is typed -> str, and its ResponseOutputText branch already coerces a possibly-None text to "" (added in #3394). The sibling ResponseOutputRefusal branch, however, returned last_content.refusal unguarded — the one remaining path in this helper that can return None despite the -> str contract.

refusal is typed str by the Responses API schema, but the same provider-gateway (e.g. LiteLLM) and model_construct streaming paths that surface a None text can surface a None refusal. This guards it with or "", matching the text branch directly above and the sibling helpers extract_text, extract_refusal, and text_message_output, which all already use or "".

Test plan

  • Added test_extract_last_content_tolerates_none_refusal_content in tests/test_items_helpers.py, mirroring the existing test_extract_text_tolerates_none_text_content: it builds a ResponseOutputRefusal.model_construct(refusal=None, ...) and asserts extract_last_content returns "" (and not None).
  • uv run pytest tests/test_items_helpers.py — 35 passed.
  • uv run ruff format and uv run ruff check are clean; uv run mypy src/agents/items.py passes.

Issue number

N/A — this completes the None-guarding introduced in #3394 (same function, text branch) and #3375 (text_message_output); the refusal branch is the lone remaining unguarded path in a helper typed -> str.

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

extract_last_content is typed -> str, and its ResponseOutputText branch
already coerces a possibly-None text to "" (openai#3394). The sibling
ResponseOutputRefusal branch returned last_content.refusal unguarded --
the lone remaining path that can return None despite the -> str contract.
Guard with `or ""` to match the text branch and the sibling helpers
extract_text, extract_refusal, and text_message_output.
@seratch

seratch commented Jul 7, 2026

Copy link
Copy Markdown
Member

We've been receiving this patch several times but we don't need the change. #3751 clarifies why we don't accept it.

@seratch seratch closed this Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants