langchain-ai/deepagents · error · OSError
temporary artifact is not owned by this user
Error message
temporary artifact is not owned by this user
What it means
Raised by `_allocate_temp_artifact` when the freshly created temp artifact's `st_uid` does not match the current process's `os.getuid()`. The library throws this to prevent trusting (and later deleting) a file that was swapped in by another local user — a classic TOCTOU hardening check on the shared temp directory.
Source
Thrown at libs/code/deepagents_code/auto_mode.py:1059
) -> AutoTempArtifact:
data = content.encode("utf-8")
temp_root = Path(tempfile.gettempdir()).absolute()
file_descriptor, raw_path = tempfile.mkstemp(
prefix=_TEMP_ARTIFACT_PREFIX,
suffix=suffix,
dir=temp_root,
)
file_path = Path(raw_path)
complete = False
try:
file_stat = _write_temp_artifact_bytes(file_descriptor, data)
if not stat.S_ISREG(file_stat.st_mode):
msg = "temporary artifact is not a regular file"
raise OSError(msg)
getuid = getattr(os, "getuid", None)
if callable(getuid) and file_stat.st_uid != getuid():
msg = "temporary artifact is not owned by this user"
raise OSError(msg)
if os.name != "nt" and stat.S_IMODE(file_stat.st_mode) & 0o077:
msg = "temporary artifact permissions are too broad"
raise OSError(msg)
artifact = AutoTempArtifact(
allocation_id=uuid4().hex,
file_path=str(file_path),
thread_key=thread_key,
turn_id=turn_id,
created_by_tool_call_id=tool_call_id,
file_device=file_stat.st_dev,
file_inode=file_stat.st_ino,
)
complete = True
return artifact
finally:
with contextlib.suppress(OSError):
os.close(file_descriptor)
if not complete:View on GitHub (pinned to a1af029e6e)
Solutions
- Ensure the process does not change uid between creating and stat-ing the file (avoid setuid helpers mid-run)
- Point `TMPDIR` at a directory owned by and writable only by the current user (e.g. a private run dir) so no other uid can race it
- Check the temp directory has the sticky bit (`ls -ld /tmp` shows `drwxrwxrwt`) and correct ownership
- If it appears in tests, verify any `os.getuid` monkeypatching matches the artifact's `st_uid`
Defensive patterns
Strategy: validation
Validate before calling
import os, tempfile, stat
tmp = tempfile.gettempdir()
st = os.stat(tmp)
if os.name == "posix":
assert st.st_uid == os.getuid() or (st.st_mode & stat.S_ISVTX), "temp dir not sticky-bit protected"
assert not (st.st_mode & 0o002 and not (st.st_mode & stat.S_ISVTX)), "world-writable temp dir without sticky bit" Try / catch
try:
artifact = create_temp_artifact(content=content, suffix=".txt")
except OSError as exc:
if "not owned by this user" in str(exc):
switch_to_private_tmpdir_and_retry()
else:
raise Prevention
- Avoid setuid/sudo transitions during an agent run
- Use a per-user private temp directory instead of a shared world-writable one
- Confirm /tmp (or TMPDIR) has the sticky bit on multi-user systems
- Keep the agent process uid constant from tool call to cleanup
When it happens
Trigger: Calling `create_temp_artifact` where the `mkstemp` result is owned by a different uid — only possible on multi-user POSIX systems if the temp directory permits it (e.g. a sticky-bit directory with hostile content, uid changes via setuid, or a symlink attack replacing the file).
Common situations: Running the agent under sudo/setuid where uid flips mid-run; a shared/writable `/tmp` where another user races the mkstemp; `TMPDIR` pointing at a world-writable directory without the sticky bit; tests monkeypatching `os.getuid` inconsistently.
Related errors
- temporary artifact permissions are too broad
- debug log directory is not owned by the current user: {path}
- Cannot determine whether {str(left)!r} is {str(right)!r}: {e
- temporary artifact is not a regular file
- temporary artifact identity changed
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/58d15b3172f0365b.
Report an issue: GitHub.