Skip to content

DRAFT: fix: disable posix_spawn on Python 3.13+ to fix libtmux race condition#1912

Draft
neubig wants to merge 1 commit intomainfrom
fix/python313-libtmux-race-condition
Draft

DRAFT: fix: disable posix_spawn on Python 3.13+ to fix libtmux race condition#1912
neubig wants to merge 1 commit intomainfrom
fix/python313-libtmux-race-condition

Conversation

@neubig
Copy link
Contributor

@neubig neubig commented Feb 4, 2026

Summary

This PR fixes the Docker/Apptainer sandboxed server example tests failing in CI (issue #1886) without downgrading Python 3.13.

Root Cause Analysis

Python 3.13 made a significant change to subprocess behavior (gh-113117):

"The subprocess module now uses the posix_spawn() function in more situations, including when close_fds is True (the default) on many modern platforms."

This causes a race condition in libtmux where:

  1. server.new_session() creates a tmux session via tmux new-session
  2. Immediately after, it queries via list-sessions to get full session info
  3. With Python 3.13's faster posix_spawn(), the query can execute before tmux has fully registered the session

The Fix

This PR disables posix_spawn specifically for Python 3.13+ before importing libtmux:

if sys.version_info >= (3, 13) and hasattr(subprocess, "_USE_POSIX_SPAWN"):
    subprocess._USE_POSIX_SPAWN = False

This is the official control knob provided by Python 3.13:

"A private control knob subprocess._USE_POSIX_SPAWN can be set to False if you need to force subprocess to never use posix_spawn()."

Alternative to PR #1910

This approach allows us to keep Python 3.13 in the Docker image instead of downgrading to Python 3.12.

Testing

The test-examples label triggers CI to:

  1. Build a new Docker image with this fix
  2. Run the example tests against that new image

Note: Local testing cannot verify this fix because it requires a Docker image built with the fix. The pre-built latest-python image doesn't contain the fix.

Fixes #1886

Python 3.13 uses posix_spawn() more aggressively for subprocess calls,
which can cause a race condition in libtmux where the list-sessions
query runs before tmux has fully registered a newly created session.

This workaround disables posix_spawn before importing libtmux to ensure
reliable session creation in PyInstaller-bundled environments.

See: https://docs.python.org/3/whatsnew/3.13.html#subprocess
Fixes #1886

Co-authored-by: openhands <[email protected]>
@neubig neubig added the test-examples Run all applicable "examples/" files. Expensive operation. label Feb 4, 2026 — with OpenHands AI
@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2026

🔄 Running Examples with openhands/claude-haiku-4-5-20251001

Generated: 2026-02-04 22:20:25 UTC

Example Status Duration Cost
01_standalone_sdk/02_custom_tools.py ✅ PASS 23.5s $0.03
01_standalone_sdk/03_activate_skill.py ✅ PASS 16.2s $0.03
01_standalone_sdk/05_use_llm_registry.py ✅ PASS 8.6s $0.01
01_standalone_sdk/07_mcp_integration.py ✅ PASS 35.0s $0.03
01_standalone_sdk/09_pause_example.py ✅ PASS 13.6s $0.01
01_standalone_sdk/10_persistence.py ✅ PASS 26.2s $0.02
01_standalone_sdk/11_async.py ✅ PASS 33.3s $0.04
01_standalone_sdk/12_custom_secrets.py ✅ PASS 12.9s $0.01
01_standalone_sdk/13_get_llm_metrics.py ✅ PASS 16.5s $0.01
01_standalone_sdk/14_context_condenser.py ✅ PASS 3m 54s $0.52
01_standalone_sdk/17_image_input.py ✅ PASS 14.4s $0.02
01_standalone_sdk/18_send_message_while_processing.py ✅ PASS 23.0s $0.01
01_standalone_sdk/19_llm_routing.py ✅ PASS 11.0s $0.02
01_standalone_sdk/20_stuck_detector.py ✅ PASS 17.3s $0.02
01_standalone_sdk/21_generate_extraneous_conversation_costs.py ✅ PASS 7.1s $0.00
01_standalone_sdk/22_anthropic_thinking.py ✅ PASS 11.5s $0.01
01_standalone_sdk/23_responses_reasoning.py ✅ PASS 1m 15s $0.01
01_standalone_sdk/24_planning_agent_workflow.py ✅ PASS 3m 14s $0.24
01_standalone_sdk/25_agent_delegation.py ✅ PASS 1m 38s $0.15
01_standalone_sdk/26_custom_visualizer.py ✅ PASS 14.3s $0.02
01_standalone_sdk/28_ask_agent_example.py ❌ FAIL
Exit code 1
33.6s --
01_standalone_sdk/29_llm_streaming.py ✅ PASS 46.5s $0.03
01_standalone_sdk/30_tom_agent.py ❌ FAIL
Exit code 1
2.3s --
01_standalone_sdk/31_iterative_refinement.py ✅ PASS 3m 30s $0.25
01_standalone_sdk/32_configurable_security_policy.py ✅ PASS 16.9s $0.02
01_standalone_sdk/34_critic_example.py ✅ PASS 1m 6s $0.00
02_remote_agent_server/01_convo_with_local_agent_server.py ✅ PASS 1m 1s $0.07
02_remote_agent_server/02_convo_with_docker_sandboxed_server.py ❌ FAIL
Exit code 1
41.5s --
02_remote_agent_server/03_browser_use_with_docker_sandboxed_server.py ❌ FAIL
Exit code 1
15.0s --
02_remote_agent_server/04_convo_with_api_sandboxed_server.py ❌ FAIL
Exit code 1
1m 9s --
02_remote_agent_server/05_vscode_with_docker_sandboxed_server.py ❌ FAIL
Exit code 1
12.7s --
02_remote_agent_server/07_convo_with_cloud_workspace.py ✅ PASS 32.2s $0.03
02_remote_agent_server/08_convo_with_apptainer_sandboxed_server.py ❌ FAIL
Exit code 1
2m 42s --
04_llm_specific_tools/01_gpt5_apply_patch_preset.py ✅ PASS 20.6s $0.02
04_llm_specific_tools/02_gemini_file_tools.py ✅ PASS 45.8s $0.07
05_skills_and_plugins/01_loading_agentskills/main.py ✅ PASS 8.5s $0.01
05_skills_and_plugins/02_loading_plugins/main.py ✅ PASS 4.8s $0.01

❌ Some tests failed

Total: 37 | Passed: 30 | Failed: 7 | Total Cost: $1.76

Failed examples:

  • examples/01_standalone_sdk/28_ask_agent_example.py: Exit code 1
  • examples/01_standalone_sdk/30_tom_agent.py: Exit code 1
  • examples/02_remote_agent_server/02_convo_with_docker_sandboxed_server.py: Exit code 1
  • examples/02_remote_agent_server/03_browser_use_with_docker_sandboxed_server.py: Exit code 1
  • examples/02_remote_agent_server/04_convo_with_api_sandboxed_server.py: Exit code 1
  • examples/02_remote_agent_server/05_vscode_with_docker_sandboxed_server.py: Exit code 1
  • examples/02_remote_agent_server/08_convo_with_apptainer_sandboxed_server.py: Exit code 1

View full workflow run

@openhands-ai
Copy link

openhands-ai bot commented Feb 4, 2026

Looks like there are a few issues preventing this PR from being merged!

  • GitHub Actions are failing:
    • Run Examples Scripts

If you'd like me to help, just leave a comment, like

@OpenHands please fix the failing actions on PR #1912 at branch `fix/python313-libtmux-race-condition`

Feel free to include any additional details that might help me get this PR into a better state.

You can manage your notification settings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test-examples Run all applicable "examples/" files. Expensive operation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docker/Apptainer sandboxed server example tests failing in CI

2 participants