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

  1. Remove the offending file (rm <path>) and let the library create a directory there.
  2. If the file holds data you need, move it elsewhere first, then re-run.
  3. 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

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


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