{"record":{"id":"c708a7a07dcbfe5d","repo":"langchain-ai/deepagents","slug":"user-cwd-must-be-absolute-got-self-user-cwd-r","errorCode":null,"errorMessage":"user_cwd must be absolute, got {self.user_cwd!r}","messagePattern":"user_cwd must be absolute, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/project_utils.py","lineNumber":41,"sourceCode":"    \"\"\"Explicit user/project path context for project-sensitive behavior.\n\n    Attributes:\n        user_cwd: Authoritative working directory from the app invocation.\n        project_root: Resolved project root for `user_cwd`, if one exists.\n    \"\"\"\n\n    user_cwd: Path\n    project_root: Path | None = None\n\n    def __post_init__(self) -> None:\n        \"\"\"Validate that path fields are absolute.\n\n        Raises:\n            ValueError: If `user_cwd` or `project_root` is not absolute.\n        \"\"\"\n        if not self.user_cwd.is_absolute():\n            msg = f\"user_cwd must be absolute, got {self.user_cwd!r}\"\n            raise ValueError(msg)\n        if self.project_root is not None and not self.project_root.is_absolute():\n            msg = f\"project_root must be absolute, got {self.project_root!r}\"\n            raise ValueError(msg)\n\n    @classmethod\n    def from_user_cwd(cls, user_cwd: str | Path) -> ProjectContext:\n        \"\"\"Build a project context from an explicit user working directory.\n\n        Args:\n            user_cwd: User invocation directory.\n\n        Returns:\n            Resolved project context.\n        \"\"\"\n        resolved_cwd = Path(user_cwd).expanduser().resolve()\n        return cls(\n            user_cwd=resolved_cwd,\n            project_root=find_project_root(resolved_cwd),","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/project_utils.py#L23-L59","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Call .resolve() (or Path.cwd() / input_path.absolute()) on user_cwd before constructing ProjectContext","Use ProjectContext.from_user_cwd(str_or_path), which normalizes to an absolute path","Reject or expand relative paths at your config boundary"],"exampleFix":"// before\nctx = ProjectContext(user_cwd=Path(\"~/project\"))\n\n// after\nctx = ProjectContext.from_user_cwd(\"~/project\")\n# or\nctx = ProjectContext(user_cwd=Path(\"~/project\").expanduser().resolve())","handlingStrategy":"validation","validationCode":"from pathlib import Path\ncwd = Path(raw_user_cwd).expanduser().resolve()\nassert cwd.is_absolute()\nctx = ProjectContext(user_cwd=cwd)","typeGuard":"def is_abs_path(p: object) -> TypeGuard[Path]:\n    return isinstance(p, Path) and p.is_absolute()","tryCatchPattern":"try:\n    ctx = ProjectContext(user_cwd=user_cwd, project_root=root)\nexcept ValueError as e:\n    raise ConfigError(f\"fix paths to be absolute: {e}\") from e","preventionTips":["Always Path.resolve() user input before constructing ProjectContext","Prefer ProjectContext.from_user_cwd which normalizes input","Reject relative paths at your configuration boundary","~ expansion is not absoluteness — expanduser() then resolve()"],"tags":["path","validation","configuration"],"backgroundTag":"path-must-be-absolute","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}