langchain-ai/deepagents · error · ValueError
project_root must be absolute, got {self.project_root!r}
Error message
project_root must be absolute, got {self.project_root!r} What it means
ValueError raised in ProjectContext.__post_init__ when project_root is provided but is a relative path. Like user_cwd, project_root must be absolute so workspace binding and path comparisons remain unambiguous across processes.
Source
Thrown at libs/code/deepagents_code/project_utils.py:44
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),
)
def resolve_user_path(self, path: str | Path) -> Path:View on GitHub (pinned to a1af029e6e)
Solutions
- Resolve the root: project_root=Path(raw).resolve() before constructing the context
- Omit project_root (None) if there is no project, instead of passing a relative placeholder
- Fix the config/source so stored project roots are absolute
Example fix
// before ctx = ProjectContext(user_cwd=cwd, project_root=Path(config["root"])) // after ctx = ProjectContext(user_cwd=cwd, project_root=Path(config["root"]).resolve())
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
root = Path(config["project_root"]).resolve() if config.get("project_root") else None
ctx = ProjectContext(user_cwd=cwd, project_root=root) Type guard
def is_abs_or_none(p: object) -> TypeGuard[Path | None]:
return p is None or (isinstance(p, Path) and p.is_absolute()) Try / catch
try:
ctx = ProjectContext(user_cwd=cwd, project_root=root)
except ValueError as e:
raise ConfigError(f"project_root must be absolute: {e}") from e Prevention
- Store project_root as an absolute path in configs
- Resolve values read from env vars or settings files
- Use None instead of a relative placeholder when there is no project
- Resolve after expanduser() for paths containing ~
When it happens
Trigger: Constructing ProjectContext(user_cwd=..., project_root=Path(".")) or any relative path; passing a relative root discovered from config or env vars. Note project_root=None is allowed.
Common situations: Reading project_root from a settings file stored as a relative path; passing "." or the result of os.getcwd() without resolve() on systems where it returns relative; partially migrated configs.
Related errors
- user_cwd must be absolute, got {self.user_cwd!r}
- {what} must be absolute: {path}
- Home directory is not absolute: {launch_home}. Set $HOME to
- Invalid {SERVER_ENV_PREFIX}ALLOW_FS_TOOLS value: unknown fil
- Invalid {SERVER_ENV_PREFIX}ALLOW_FS_TOOLS value: {raw!r}; ex
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/4ef5ecc80aa2ae63.
Report an issue: GitHub.