{"record":{"id":"ad75fbcba1a0adb7","repo":"langchain-ai/deepagents","slug":"debug-log-directory-is-not-owned-by-the-current-us","errorCode":null,"errorMessage":"debug log directory is not owned by the current user: {path}","messagePattern":"debug log directory is not owned by the current user: (.+?)","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/_debug.py","lineNumber":311,"sourceCode":"    Raises:\n        OSError: If the directory cannot be created, opened, or tightened.\n    \"\"\"\n    with contextlib.suppress(FileExistsError):\n        path.mkdir(mode=0o700)\n    if os.name == \"nt\":\n        metadata = path.lstat()\n        if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):\n            msg = f\"debug log directory is not a real directory: {path}\"\n            raise OSError(msg)\n        _set_windows_owner_only_dacl(path)\n        return\n    flags = os.O_RDONLY | getattr(os, \"O_DIRECTORY\", 0) | getattr(os, \"O_NOFOLLOW\", 0)\n    fd = os.open(path, flags)\n    try:\n        metadata = os.fstat(fd)\n        if metadata.st_uid != os.geteuid():\n            msg = f\"debug log directory is not owned by the current user: {path}\"\n            raise OSError(msg)\n        os.fchmod(fd, 0o700)\n    finally:\n        os.close(fd)\n\n\ndef _thread_log_name(thread_id: str) -> str:\n    \"\"\"Return a traversal-safe log filename for a thread identifier.\"\"\"\n    if (\n        len(thread_id) <= _MAX_THREAD_FILENAME_LENGTH\n        and _SAFE_THREAD_ID.fullmatch(thread_id)\n        and thread_id not in {\".\", \"..\"}\n    ):\n        return f\"{thread_id}.log\"\n    digest = hashlib.sha256(thread_id.encode()).hexdigest()[:16]\n    return f\"thread-{digest}.log\"\n\n\ndef _remove_debug_handlers(","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/_debug.py#L293-L329","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Change ownership of the directory to the current user: chown -R $(id -u) <path>.","Remove the directory (rm -rf <path>) so the library recreates it with the correct owner and 0o700 mode.","Run the process under the account that owns the existing directory."],"exampleFix":"// before: dir owned by root\nsudo chown -R $(whoami) ~/.cache/deepagents/debug\n// after: owned by current user, run without sudo","handlingStrategy":"try-catch","validationCode":"import os\np = Path(debug_dir)\nif p.exists() and os.name != 'nt':\n    if p.stat().st_uid != os.geteuid():\n        raise SystemExit(f'{p} owned by uid {p.stat().st_uid}; fix ownership first')","typeGuard":null,"tryCatchPattern":"try:\n    bind_debug_logging_to_thread(thread_id)\nexcept OSError as exc:\n    if 'not owned by the current user' in str(exc):\n        shutil.rmtree(path, ignore_errors=True)\n        bind_debug_logging_to_thread(thread_id)","preventionTips":["Never run the app with sudo for first-run setup; run as the service user.","In Dockerfiles, create the debug dir with the same USER that runs at runtime.","Avoid pre-creating cache dirs in shared images or via admin accounts."],"tags":["permissions","ownership","filesystem","security"],"backgroundTag":"directory-ownership-mismatch","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}