langchain-ai/deepagents · error · DeepAgentsHomeError
Invalid DEEPAGENTS_HOME {str(root)!r}: exists but is not a d
Error message
Invalid DEEPAGENTS_HOME {str(root)!r}: exists but is not a directory. What it means
An existing DEEPAGENTS_HOME must be a directory; if it exists but is a regular file, symlink-to-file, socket, etc., _reject_degenerate_root raises DeepAgentsHomeError. The profile root owns everything beneath it, so a non-directory cannot serve as the root.
Source
Thrown at libs/code/deepagents_code/_paths.py:706
it may not read, so checking state first reports the permission problem
itself instead of the comparison that failed because of it.
Raises:
DeepAgentsHomeError: If the root is one of those cases.
"""
state = classify_path(root)
if state is PathState.UNREADABLE:
# Checked before the symlink branch too: `Path.is_symlink` swallows the
# `OSError` and reports `False` under EACCES, so an unreadable root
# would otherwise fall through every check and be accepted.
msg = (
f"Invalid DEEPAGENTS_HOME {str(root)!r}: exists but cannot be read. "
"Check the permissions on it and on its parent directories."
)
raise DeepAgentsHomeError(msg)
if state is PathState.EXISTS and not root.is_dir():
msg = f"Invalid DEEPAGENTS_HOME {str(root)!r}: exists but is not a directory."
raise DeepAgentsHomeError(msg)
if state is PathState.EXISTS and not os.access(root, os.R_OK | os.X_OK):
msg = (
f"Invalid DEEPAGENTS_HOME {str(root)!r}: exists but cannot be read "
"or searched. Check the permissions on it and on its parent "
"directories."
)
raise DeepAgentsHomeError(msg)
# `root` is normalized-absolute, so `anchor` is always set.
if root.parent == root or _same_directory(root, Path(root.anchor)):
msg = (
f"Invalid DEEPAGENTS_HOME {str(root)!r}: the filesystem root cannot "
"be a profile. Use a dedicated directory."
)
raise DeepAgentsHomeError(msg)
if launch_home is not None and _same_directory(root, launch_home):
msg = (
f"Invalid DEEPAGENTS_HOME {str(root)!r}: the home directory itself "
"cannot be a profile, because its '.env' would be loaded as "View on GitHub (pinned to a1af029e6e)
Solutions
- Remove the offending file (rm <path>) and let the library create a directory there.
- If the file holds data you need, move it elsewhere first, then re-run.
- Point DEEPAGENTS_HOME at an intended directory instead of a file path.
Example fix
// before: ~/.deepagents is a regular file mv ~/.deepagents ~/.deepagents.bak # inspect, then discard // after: run the app; it mkdirs ~/.deepagents as a directory
Defensive patterns
Strategy: validation
Validate before calling
import os
from pathlib import Path
root = Path(os.environ.get('DEEPAGENTS_HOME', ''))
if root.exists() and not root.is_dir():
root.rename(root.with_suffix('.bak')) # move the stray file aside Type guard
def is_existing_dir(p: Path) -> bool:
return p.is_dir() and not p.is_symlink() Try / catch
try:
root = _resolve_profile_root()
except DeepAgentsHomeError as exc:
if 'is not a directory' in str(exc):
target = Path(os.environ['DEEPAGENTS_HOME'])
target.rename(target.with_suffix('.bak'))
root = _resolve_profile_root()
else:
raise Prevention
- Never redirect shell output to the profile-root path.
- Check for stray files at expected directory locations after extractions.
- Point DEEPAGENTS_HOME at directories, not config-file paths.
When it happens
Trigger: DEEPAGENTS_HOME points at a path that exists as a non-directory — e.g. a stray file named '.deepagents' created by a redirect (touch or command output) where a directory was expected.
Common situations: Shell redirect like 'cmd > ~/.deepagents' creating a file; tar/backup extraction leaving a file where the dir should be; typos pointing DEEPAGENTS_HOME at a config file path.
Related errors
- {what} must be absolute: {path}
- Home directory is not absolute: {launch_home}. Set $HOME to
- Cannot determine whether {str(left)!r} is {str(right)!r}: {e
- Invalid DEEPAGENTS_HOME {str(root)!r}: exists but cannot be
- Marketplace URL {_redact_url_credentials(url)} only download
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/ceec65247f792eb9.
Report an issue: GitHub.