langchain-ai/deepagents · error · ValueError

workspace.{field} must be an absolute path without traversal

Error message

workspace.{field} must be an absolute path without traversal

What it means

Raised when a workspace path is either relative or contains '..' traversal segments. _canonical_directory requires absolute paths and forbids traversal to keep workspaces confined to an explicit location. This runs after the non-empty/length check and before filesystem resolution.

Source

Thrown at libs/code/deepagents_code/workspace.py:77


def _database_path() -> Path:
    value = os.environ.get(f"{SERVER_ENV_PREFIX}DB_PATH")
    if value:
        return Path(value)
    from deepagents_code.sessions import get_db_path

    return get_db_path()


def _canonical_directory(value: object, *, field: str) -> Path:
    if not isinstance(value, str) or not value or len(value) > _MAX_PATH_LENGTH:
        msg = f"workspace.{field} must be a non-empty absolute path"
        raise ValueError(msg)
    candidate = Path(value)
    if not candidate.is_absolute() or ".." in PurePath(value).parts:
        msg = f"workspace.{field} must be an absolute path without traversal"
        raise ValueError(msg)
    if os.name != "nt":
        from deepagents.backends.utils import validate_path

        validate_path(value)
    try:
        resolved = candidate.resolve(strict=True)
    except (OSError, RuntimeError) as exc:
        msg = f"workspace.{field} is unavailable: {value}"
        raise ValueError(msg) from exc
    if not resolved.is_dir():
        msg = f"workspace.{field} is not a directory: {value}"
        raise ValueError(msg)
    if os.name != "nt":
        from deepagents.backends.utils import validate_path

        validate_path(str(resolved))
    return resolved

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Use an absolute path with no '..' components, e.g. /home/me/project.
  2. Expand '~' with os.path.expanduser and absolutize with Path.resolve()/abspath before calling.
  3. Strip or normalize '..' segments in paths built from user input.

Example fix

// before
resolve_workspace(workspace={'dir': '~/work'})
// after
import os
resolve_workspace(workspace={'dir': os.path.expanduser('~/work')})
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path, PurePath
import os

def absolutize(value: str) -> str:
    expanded = os.path.expanduser(value)
    absolute = str(Path(expanded).absolute())
    if '..' in PurePath(absolute).parts:
        raise ValueError('.. segments not allowed')
    return absolute

Type guard

def is_absolute_no_traversal(value: str) -> bool:
    p = PurePath(value)
    return p.is_absolute() and '..' not in p.parts

Try / catch

try:
    ws = resolve_workspace(workspace={'dir': cfg['dir']})
except ValueError as e:
    logger.error('workspace path must be absolute without traversal: %s', e)

Prevention

When it happens

Trigger: Calling resolve_workspace with workspace.{field} like 'myproject', './myproject', '/a/b/../../etc', or any path where PurePath parts contain '..'.

Common situations: Configured with a relative path because a tilde/env expansion never happened ('~/work' is not absolute until expanded); '..' segments introduced by joining user-supplied segments; security policy rejecting traversal.

Related errors


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