Please read this first
- Have you read the docs? Yes. I checked the sandbox artifact implementation and existing
GitRepo tests.
- Have you searched for related issues? Yes. I searched issues/PRs.
Describe the bug
GitRepo.apply() creates a temporary clone directory under /tmp/sandbox-git-... inside the sandbox container. The successful path removes this temporary directory after copying the repo contents into the destination, but failures after a successful clone can skip cleanup.
For example, if cp -R fails because the requested subpath is missing or the destination copy fails, GitCopyError is raised before the final cleanup command runs. This can leave cloned repository contents behind in /tmp, including private repository content, and can also grow sandbox disk usage over repeated failures.
Debug information
- Agents SDK version:
0.16.0
- Source revision tested:
eed9100
- Python version: Python 3.12.1
Repro steps
Run this from the repository root on current main:
import asyncio
from pathlib import Path
from agents.sandbox.entries import GitRepo
from agents.sandbox.errors import GitCopyError
from agents.sandbox.types import ExecResult
from tests.sandbox.test_entries import _RecordingSession
class CopyFailSession(_RecordingSession):
async def _exec_internal(self, *command, timeout=None):
cmd = tuple(str(part) for part in command)
self.exec_calls.append(cmd)
if cmd == ("command -v git >/dev/null 2>&1",):
return ExecResult(stdout=b"/usr/bin/git\n", stderr=b"", exit_code=0)
if cmd[:1] == ("cp",):
return ExecResult(stdout=b"", stderr=b"copy failed", exit_code=1)
return ExecResult(stdout=b"", stderr=b"", exit_code=0)
async def main() -> None:
session = CopyFailSession()
try:
await GitRepo(repo="openai/example", ref="main").apply(
session,
Path("/workspace/repo"),
Path("/ignored"),
)
except GitCopyError:
print("copy_error: True")
cleanup_calls = [call for call in session.exec_calls if call[:3] == ("rm", "-rf", "--")]
print("cleanup_calls:", len(cleanup_calls))
print("cleanup_commands:", cleanup_calls)
asyncio.run(main())
Actual output:
copy_error: True
cleanup_calls: 1
cleanup_commands: [('rm', '-rf', '--', '/tmp/sandbox-git-...')]
The single cleanup call is the pre-clone cleanup before the temporary path is created. There is no cleanup after the failed copy.
Expected behavior
GitRepo.apply() should remove the temporary clone directory in a finally block after clone/fetch starts, so cleanup runs even if clone, mkdir/copy, subpath copy, or metadata-adjacent operations fail.
Please read this first
GitRepotests.Describe the bug
GitRepo.apply()creates a temporary clone directory under/tmp/sandbox-git-...inside the sandbox container. The successful path removes this temporary directory after copying the repo contents into the destination, but failures after a successful clone can skip cleanup.For example, if
cp -Rfails because the requestedsubpathis missing or the destination copy fails,GitCopyErroris raised before the final cleanup command runs. This can leave cloned repository contents behind in/tmp, including private repository content, and can also grow sandbox disk usage over repeated failures.Debug information
0.16.0eed9100Repro steps
Run this from the repository root on current
main:Actual output:
The single cleanup call is the pre-clone cleanup before the temporary path is created. There is no cleanup after the failed copy.
Expected behavior
GitRepo.apply()should remove the temporary clone directory in afinallyblock after clone/fetch starts, so cleanup runs even if clone, mkdir/copy, subpath copy, or metadata-adjacent operations fail.