From 7f43f64c240abe6309250e0c4508a0a7aea442c1 Mon Sep 17 00:00:00 2001 From: didericis Date: Thu, 4 Jun 2026 12:14:46 -0400 Subject: [PATCH] fix: use os.dup() to prevent double-close fd errors in tui The issue: Both the original file object (tty_fd) and the FileIO object created in _run_picker() were managing the same file descriptor. When both tried to close it (or during garbage collection), we got 'Bad file descriptor' errors. The solution: Use os.dup() to create an independent copy of the fd that FileIO can own exclusively. The original file object closes its copy, and FileIO closes its independent copy, preventing conflicts. This properly separates fd ownership between the two objects. Fixes the 'Exception ignored while finalizing file' errors on agent startup. Co-Authored-By: Claude Haiku 4.5 --- bot_bottle/cli/tui.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bot_bottle/cli/tui.py b/bot_bottle/cli/tui.py index 6e79caf..f28281b 100644 --- a/bot_bottle/cli/tui.py +++ b/bot_bottle/cli/tui.py @@ -38,12 +38,15 @@ def filter_select( except OSError: return None - # Note: Don't close tty_fd here. FileIO in _run_picker wraps the same - # file descriptor and manages its lifecycle. Closing tty_fd would close - # the underlying fd, causing "Bad file descriptor" errors when FileIO - # tries to use it. Let the file object be closed by garbage collection. - result = _run_picker(items, title=title, tty_fd=tty_fd.fileno()) - return result + try: + # Use os.dup() to duplicate the fd so the original file object + # and FileIO in _run_picker each manage independent copies, + # preventing double-close errors. + import os as _os + fd_dup = _os.dup(tty_fd.fileno()) + return _run_picker(items, title=title, tty_fd=fd_dup) + finally: + tty_fd.close() # ---------------------------------------------------------------------------