fix: use os.dup() to prevent double-close fd errors in tui
test / unit (pull_request) Successful in 33s
test / integration (pull_request) Successful in 41s
lint / lint (push) Successful in 1m25s
test / unit (push) Successful in 36s
test / integration (push) Successful in 48s

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 <noreply@anthropic.com>
This commit was merged in pull request #187.
This commit is contained in:
2026-06-04 12:14:46 -04:00
parent 059bba8c4f
commit 7f43f64c24
+9 -6
View File
@@ -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()
# ---------------------------------------------------------------------------