{"record":{"id":"e959e5b6f8691963","repo":"langchain-ai/deepagents","slug":"path-must-start-with-one-of-allowed-prefixes-p","errorCode":null,"errorMessage":"Path must start with one of {allowed_prefixes}: {path}","messagePattern":"Path must start with one of (.+?): (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/backends/utils.py","lineNumber":722,"sourceCode":"    # Reject Windows absolute paths (e.g., C:\\..., D:/...)\n    if re.match(r\"^[a-zA-Z]:\", path):\n        msg = f\"Windows absolute paths are not supported: {path}. Please use virtual paths starting with / (e.g., /workspace/file.txt)\"\n        raise ValueError(msg)\n\n    normalized = os.path.normpath(path)\n    normalized = normalized.replace(\"\\\\\", \"/\")\n\n    if not normalized.startswith(\"/\"):\n        normalized = f\"/{normalized}\"\n\n    # Defense-in-depth: verify normpath didn't produce traversal\n    if \"..\" in normalized.split(\"/\"):\n        msg = f\"Path traversal detected after normalization: {path} -> {normalized}\"\n        raise ValueError(msg)\n\n    if allowed_prefixes is not None and not any(normalized.startswith(prefix) for prefix in allowed_prefixes):\n        msg = f\"Path must start with one of {allowed_prefixes}: {path}\"\n        raise ValueError(msg)\n\n    return normalized\n\n\ndef _normalize_path(path: str | None) -> str:\n    \"\"\"Normalize a path to canonical form.\n\n    Converts path to absolute form starting with /, removes trailing slashes\n    (except for root), and validates that the path is not empty.\n\n    Args:\n        path: Path to normalize (None defaults to \"/\")\n\n    Returns:\n        Normalized path starting with / (without trailing slash unless it's root)\n\n    Raises:\n        ValueError: If path is invalid (empty string after strip)","sourceCodeStart":704,"sourceCodeEnd":740,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/backends/utils.py#L704-L740","documentation":"validate_path enforces an allowlist of path prefixes. If the normalized path does not start with any of the configured allowed_prefixes, a ValueError is raised, keeping all backend operations confined to permitted directories (e.g. the agent workspace root).","triggerScenarios":"Calling a backend file operation with a path outside the configured allowed prefixes — e.g. validate_path('/etc/passwd') when allowed_prefixes=['/workspace/'] — or a path like '/workspace2/x' when the prefix '/workspace' (without trailing slash) is not in the list.","commonSituations":"Pointing tools at files outside the sandbox root; misconfigured allowed_prefixes (e.g. missing trailing slash); agents composing absolute paths from user input that escapes the root.","solutions":["Use a path starting with one of the allowed prefixes (they are listed in the error message).","Update backend configuration to include the intended root in allowed_prefixes.","Convert relative paths to absolute paths under the allowed root before calling.","Catch ValueError and prompt the user/agent to retry with a path inside the permitted root."],"exampleFix":"// before\nbackend.read(\"/etc/hosts\")  # prefix not allowed\n// after\nbackend.read(\"/workspace/notes/hosts_copy.txt\")  # inside allowed prefix","handlingStrategy":"validation","validationCode":"def is_within_allowed(path: str, prefixes: list[str]) -> bool:\n    import posixpath\n    normalized = posixpath.normpath(path)\n    return any(normalized.startswith(p) for p in prefixes)","typeGuard":"def starts_with_prefix(path: str, prefixes: tuple[str, ...]) -> bool:\n    return isinstance(path, str) and any(path.startswith(p) for p in prefixes)","tryCatchPattern":"try:\n    backend.write(path, data)\nexcept ValueError as exc:\n    if str(exc).startswith(\"Path must start with one of\"):\n        return {\"error\": \"Path outside permitted roots; choose a path inside the workspace\"}\n    raise","preventionTips":["Keep allowed_prefixes entries ending with '/' to avoid partial-prefix matches.","Resolve relative paths against the workspace root before calling backend APIs.","Validate agent-generated absolute paths against the prefix allowlist first.","Log rejected paths to spot agents repeatedly attempting out-of-root access."],"tags":["path-traversal","security","allowlist"],"backgroundTag":"path-not-allowed","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}