langchain-ai/deepagents · error · ValueError

user_cwd must be absolute, got {self.user_cwd!r}

Error message

user_cwd must be absolute, got {self.user_cwd!r}

What it means

ValueError raised in ProjectContext.__post_init__ when user_cwd is a relative path. ProjectContext requires absolute paths because the working directory is serialized into workspace payloads and resolved from arbitrary call sites, where relative paths would be ambiguous.

Source

Thrown at libs/code/deepagents_code/project_utils.py:41

    """Explicit user/project path context for project-sensitive behavior.

    Attributes:
        user_cwd: Authoritative working directory from the app invocation.
        project_root: Resolved project root for `user_cwd`, if one exists.
    """

    user_cwd: Path
    project_root: Path | None = None

    def __post_init__(self) -> None:
        """Validate that path fields are absolute.

        Raises:
            ValueError: If `user_cwd` or `project_root` is not absolute.
        """
        if not self.user_cwd.is_absolute():
            msg = f"user_cwd must be absolute, got {self.user_cwd!r}"
            raise ValueError(msg)
        if self.project_root is not None and not self.project_root.is_absolute():
            msg = f"project_root must be absolute, got {self.project_root!r}"
            raise ValueError(msg)

    @classmethod
    def from_user_cwd(cls, user_cwd: str | Path) -> ProjectContext:
        """Build a project context from an explicit user working directory.

        Args:
            user_cwd: User invocation directory.

        Returns:
            Resolved project context.
        """
        resolved_cwd = Path(user_cwd).expanduser().resolve()
        return cls(
            user_cwd=resolved_cwd,
            project_root=find_project_root(resolved_cwd),

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Call .resolve() (or Path.cwd() / input_path.absolute()) on user_cwd before constructing ProjectContext
  2. Use ProjectContext.from_user_cwd(str_or_path), which normalizes to an absolute path
  3. Reject or expand relative paths at your config boundary

Example fix

// before
ctx = ProjectContext(user_cwd=Path("~/project"))

// after
ctx = ProjectContext.from_user_cwd("~/project")
# or
ctx = ProjectContext(user_cwd=Path("~/project").expanduser().resolve())
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
cwd = Path(raw_user_cwd).expanduser().resolve()
assert cwd.is_absolute()
ctx = ProjectContext(user_cwd=cwd)

Type guard

def is_abs_path(p: object) -> TypeGuard[Path]:
    return isinstance(p, Path) and p.is_absolute()

Try / catch

try:
    ctx = ProjectContext(user_cwd=user_cwd, project_root=root)
except ValueError as e:
    raise ConfigError(f"fix paths to be absolute: {e}") from e

Prevention

When it happens

Trigger: Constructing ProjectContext(...) directly (or via code paths that bypass from_user_cwd) with a relative Path like Path(".") or Path("src") instead of an absolute path.

Common situations: Building a ProjectContext from user input or CLI args without calling Path.resolve()/absolute(); passing a shell variable that is empty or relative; constructing the context in a library without knowing the caller's cwd.

Related errors


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