[linux sandbox] failed socket write hangs python asyncio

Resolved 💬 1 comment Opened Nov 7, 2025 by cg505 Closed Jan 28, 2026

What version of Codex is running?

codex-cli 0.55.0

What subscription do you have?

plus

Which model were you using?

n/a

What platform is your computer?

Linux 6.17.7-arch1-1 x86_64 unknown

What issue are you seeing?

In the Linux sandbox, unix sockets cannot be used.
In practice this causes really weird random hangs in the python asyncio runtime, which relies on socket pairs for cross-thread wakeup signaling.

Creating the socket/socketpair is explicitly allowed, but reading/writing is blanket banned (except for recvfrom?), making the socket seemingly useless. It seems reading/writing should be possible.

In python, the asyncio runtime uses a unix socketpair to trigger a wakeup when an async future is resolved across threads. Specifically, the async event loop holds a socketpair, and to signal new events from another thread, a null byte is written into the socketpair. On the main event loop thread, asyncio epolls the other end of the socketpair. This just breaks in the codex

What steps can reproduce the bug?

Here's an example python program that shows that writing to a socketpair does not work:

import socket
sock1, sock2 = socket.socketpair()
sock1.send(b'\x00')

Here's an example python program showing the asyncio hang:

import asyncio
import threading
import time

def set_result(future, value):
    """Async function that sets the result of a future."""
    print(f"set_result called with value: {value}")
    future.set_result(value)

def second_thread(loop, future):
    """Function running in the second thread."""
    print("Second thread started, waiting 1 second...")
    time.sleep(1)

    print("Second thread calling set_result via call_soon_threadsafe...")
    # This is the problematic line - it will not wake up the event loop and
    # set_result will never be called.
    loop.call_soon_threadsafe(set_result, future, "Hello from second thread!")

async def main():
    """Main async function."""
    print("Main thread creating event loop and future...")
    loop = asyncio.get_running_loop()
    future = loop.create_future()

    # Start the second thread
    thread = threading.Thread(target=second_thread, args=(loop, future))
    thread.start()

    print("Main thread awaiting future...")
    result = await future
    print(f"Future completed with result: {result}")

    thread.join()
    print("Done!")

if __name__ == "__main__":
    asyncio.run(main())

This works consistently outside the sandbox, and hangs consistently with the sandbox. This cross-thread pattern is used by the library aiosqlite.

What is the expected behavior?

_No response_

Additional information

_No response_

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗