langchain-ai/deepagents · error · OSError

debug log directory is not owned by the current user: {path}

Error message

debug log directory is not owned by the current user: {path}

What it means

On POSIX, _prepare_debug_directory opens the debug log directory with O_NOFOLLOW and compares the fstat owner to the effective uid. If the directory exists but is owned by a different user, the library refuses to use it, since writing debug logs into another user's directory would be unsafe. This guards against pre-created or hijacked directories.

Source

Thrown at libs/code/deepagents_code/_debug.py:311

    Raises:
        OSError: If the directory cannot be created, opened, or tightened.
    """
    with contextlib.suppress(FileExistsError):
        path.mkdir(mode=0o700)
    if os.name == "nt":
        metadata = path.lstat()
        if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):
            msg = f"debug log directory is not a real directory: {path}"
            raise OSError(msg)
        _set_windows_owner_only_dacl(path)
        return
    flags = os.O_RDONLY | getattr(os, "O_DIRECTORY", 0) | getattr(os, "O_NOFOLLOW", 0)
    fd = os.open(path, flags)
    try:
        metadata = os.fstat(fd)
        if metadata.st_uid != os.geteuid():
            msg = f"debug log directory is not owned by the current user: {path}"
            raise OSError(msg)
        os.fchmod(fd, 0o700)
    finally:
        os.close(fd)


def _thread_log_name(thread_id: str) -> str:
    """Return a traversal-safe log filename for a thread identifier."""
    if (
        len(thread_id) <= _MAX_THREAD_FILENAME_LENGTH
        and _SAFE_THREAD_ID.fullmatch(thread_id)
        and thread_id not in {".", ".."}
    ):
        return f"{thread_id}.log"
    digest = hashlib.sha256(thread_id.encode()).hexdigest()[:16]
    return f"thread-{digest}.log"


def _remove_debug_handlers(

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Change ownership of the directory to the current user: chown -R $(id -u) <path>.
  2. Remove the directory (rm -rf <path>) so the library recreates it with the correct owner and 0o700 mode.
  3. Run the process under the account that owns the existing directory.

Example fix

// before: dir owned by root
sudo chown -R $(whoami) ~/.cache/deepagents/debug
// after: owned by current user, run without sudo
Defensive patterns

Strategy: try-catch

Validate before calling

import os
p = Path(debug_dir)
if p.exists() and os.name != 'nt':
    if p.stat().st_uid != os.geteuid():
        raise SystemExit(f'{p} owned by uid {p.stat().st_uid}; fix ownership first')

Try / catch

try:
    bind_debug_logging_to_thread(thread_id)
except OSError as exc:
    if 'not owned by the current user' in str(exc):
        shutil.rmtree(path, ignore_errors=True)
        bind_debug_logging_to_thread(thread_id)

Prevention

When it happens

Trigger: bind_debug_logging_to_thread is called while the resolved debug log directory already exists and its st_uid differs from os.geteuid() — e.g. the directory was created by root or another account.

Common situations: First run under sudo created the directory as root; a shared multi-user machine where an admin pre-created the path; container where the image build made the directory under a different uid than the runtime user.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/ad75fbcba1a0adb7. Report an issue: GitHub.