Repository navigation
Description
Running the sandbox suite on Windows as a normal, non-elevated user:
tests/sandbox/test_tar_utils.py + test_workspace_paths.py:
12 failed, 93 passed, 15 skipped
All twelve fail with OSError: [WinError 1314] A required privilege is not held by the client. Windows permits symlink creation only for an elevated process or with Developer Mode enabled — neither is the default.
They split into two distinct problems.
- Product: safe_extract_tarfile cannot extract archives containing symlinks
Seven of the failures originate in library code, not test setup:
tests/sandbox/test_tar_utils.py:75: in _safe_extract
src/agents/sandbox/util/tar_utils.py:468: in safe_extract_tarfile
E OSError: [WinError 1314] A required privilege is not held by the client:
'/usr/local/bin/python3' -> '...\link.txt'
tar_utils.py:468:
for member in members:
if not member.issym():
continue
rel_path = safe_tar_member_rel_path(member, allow_symlinks=True)
if rel_path is None:
continue
dest = root_resolved / rel_path
_prepare_replaceable_leaf(dest=dest, rel_path=rel_path, name=member.name)
os.symlink(member.linkname, dest)
There is no platform handling anywhere in that file. So on an ordinary Windows machine, extracting any archive that contains a symlink member raises, aborting the extraction partway — after the regular files have already been written.
Affected tests, all exercising real extraction behaviour:
test_safe_extract_tarfile_can_rehydrate_existing_leaf_symlink
test_safe_extract_tarfile_can_replace_existing_leaf_file_with_symlink
test_safe_extract_tarfile_can_replace_existing_leaf_symlink_with_file
test_safe_extract_tarfile_can_replace_existing_leaf_symlink_with_directory
test_safe_extract_tarfile_rejects_preexisting_symlink_parent
test_safe_extract_tarfile_rejects_symlink_under_preexisting_symlink_parent
(and one more in the same file)
I have deliberately not proposed a patch for this half. The sandbox has security semantics around symlinks — safe_tar_member_rel_path(..., allow_symlinks=True), escape rejection, _prepare_replaceable_leaf — and the options each carry different meaning:
Skip symlink members on Windows. Extraction completes, but the result silently differs from the archive, which may matter for a sandbox that later validates paths.
Raise a clear, typed error. Honest, but still fails the operation.
Materialise as a copy of the target. Preserves content, changes escape semantics — a copy cannot point outside the root, so some of the existing protections become moot.
Which of those is right is a maintainer decision, not one I should make from outside.
- Tests: unguarded symlink creation in test setup
The other five come from the tests themselves, e.g. tests/sandbox/test_workspace_paths.py:798:
os.symlink(target, workspace / "link.txt")
Nothing guards these, and there is no module-level skip or marker.
test_normalize_path_with_symlink_resolution
test_host_io_rejects_write_under_resolved_read_only_extra_path_grant
test_host_io_rejects_extra_path_grant_symlink_to_root
test_host_path_grant_rejects_symlink_to_root
test_host_path_grant_returns_validated_resolved_source
This half is straightforward and I am happy to submit a PR: a small symlink_or_skip() helper used at the affected call sites, so the tests skip with a clear reason where the platform refuses rather than erroring. That is the same approach psf/black uses for its symlink tests.
Why CI doesn't catch either
tests-windows in .github/workflows/tests.yml runs uv run pytest — the full suite, including tests/sandbox/ — on windows-latest, and it is green. GitHub's Windows runners can create symlinks; an ordinary user cannot. So both problems are invisible to CI on the very platform it covers, and appear only on a contributor's or user's machine.
Environment
Windows-11-10.0.26200-SP0
Python 3.13.15
openai-agents-python at HEAD, uv sync dev environment
Non-elevated shell, Developer Mode off
Reproduction
git clone https://github.com/openai/openai-agents-python
cd openai-agents-python
uv sync
uv run pytest tests/sandbox/test_tar_utils.py tests/sandbox/test_workspace_paths.py
Note: a wider tests/sandbox/ run also reports failures in test_docker.py, test_docker_network_mode.py and test_mount_security.py, but those are a missing docker module in my environment and are unrelated to this report.
Activity
Hughhhhcoder commentedon Sep 8, 2026
The test-setup half is now fixed on
mainby #4853 (1e5f3ae3): the five workspace-path tests use a helper that skips only WindowsWinError 1314and re-raises other symlink errors. The remaining open part of this issue is therefore the product behavior ofsafe_extract_tarfile()when an archive contains symlinks on a Windows host without symlink privilege; that still needs the maintainer semantic choice described above.seratch commentedon Sep 20, 2026
Thanks for separating the test failures from the runtime question. #4853 addressed the workspace-path test setup. As discussed in #4948, safe_extract_tarfile() is used at runtime by UnixLocal, which explicitly does not support Windows; supported Windows backends do not use that host-side extraction path.
I'm closing this mixed-scope issue on that basis. The remaining tar-test failures on Windows without symlink privileges should be tracked separately as test portability work. This does not mean every test in the original report is fixed, and it does not add Windows support to UnixLocal.