fix: close audio file handle in OpenAITools.transcribe_audio (resource leak)#8161
Merged
sannya-singal merged 5 commits intoJun 1, 2026
Conversation
…rce leak) `OpenAITools.transcribe_audio` was opening the audio file with a bare `open(audio_path, "rb")` whose result was bound to a local variable and never explicitly closed. On every call — success OR failure — the file descriptor leaked. For an agent invoking transcription in a loop (e.g. batch processing, streaming audio chunks), this exhausts the process's `RLIMIT_NOFILE` and the next `open()` raises `OSError: [Errno 24] Too many open files`. The fix wraps the call in a `with open(...) as audio_file:` block so the file is closed deterministically at the end of the API call regardless of whether `audio.transcriptions.create(...)` succeeds or raises. No behavior change in the success or failure paths beyond the close — the OpenAI SDK reads the file fully during the request, so closing it right after the response is returned is safe. ## Regression test `tests/unit/tools/test_openai_tools.py::test_transcribe_audio_uses_context_manager_to_close_audio_file` asserts via `inspect.getsource` that the function body uses `with open(...)` and does NOT contain the buggy `audio_file = open(...)` assignment pattern, so a future revert would fail in CI immediately.
This was referenced May 30, 2026
Replace the source-string assertions with behavioral tests that mock the OpenAI client and assert the audio file handle is actually closed after the call -- on the success path, on the error path, and across repeated calls so a descriptor leak (or a revert to a bare open()) is caught.
Contributor
Author
|
Thanks for the review! I've rewritten the tests to validate behavior instead of matching source strings.
I also dropped the docstring describing the previous behavior and kept it to what the tests verify. |
Contributor
Author
|
Thanks! Addressed both points:
|
sannya-singal
approved these changes
Jun 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #8160
Summary
OpenAITools.transcribe_audiowas opening the audio file with a bareopen(audio_path, "rb")whose result was bound to a local variable and never explicitly closed. On every call — success OR failure — the file descriptor leaked. For an agent invoking transcription in a loop (batch processing, streaming audio chunks), this exhausts the process'sRLIMIT_NOFILEand the nextopen()raisesOSError: [Errno 24] Too many open files.The fix wraps the call in a
with open(...) as audio_file:block so the file is closed deterministically at the end of the API call regardless of whetheraudio.transcriptions.create(...)succeeds or raises.No behavior change in the success or failure paths beyond the close — the OpenAI SDK reads the file fully during the request, so closing it right after the response is returned is safe.
Affected location
libs/agno/agno/tools/openai.py:90— insideOpenAITools.transcribe_audio. One change:audio_file = open(audio_path, "rb")→with open(audio_path, "rb") as audio_file:(and indenting the API call into thewithbody).Regression test
tests/unit/tools/test_openai_tools.py::test_transcribe_audio_uses_context_manager_to_close_audio_fileasserts viainspect.getsourcethat the function body useswith open(...)and does NOT contain the buggyaudio_file = open(...)assignment pattern, so a future revert would fail in CI immediately.Type of change
Checklist