{"record":{"id":"53e31ca3fa73596c","repo":"langchain-ai/deepagents","slug":"path-cannot-be-empty","errorCode":null,"errorMessage":"Path cannot be empty","messagePattern":"Path cannot be empty","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/backends/utils.py","lineNumber":751,"sourceCode":"    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)\n\n    Example:\n        _normalize_path(None) -> \"/\"\n        _normalize_path(\"/dir/\") -> \"/dir\"\n        _normalize_path(\"dir\") -> \"/dir\"\n        _normalize_path(\"/\") -> \"/\"\n    \"\"\"\n    path = path or \"/\"\n    if not path or path.strip() == \"\":\n        msg = \"Path cannot be empty\"\n        raise ValueError(msg)\n\n    normalized = path if path.startswith(\"/\") else \"/\" + path\n\n    # Only root should have trailing slash\n    if normalized != \"/\" and normalized.endswith(\"/\"):\n        normalized = normalized.rstrip(\"/\")\n\n    return normalized\n\n\ndef _filter_files_by_path(files: dict[str, Any], normalized_path: str) -> dict[str, Any]:\n    \"\"\"Filter files dict by normalized path, handling exact file matches and directory prefixes.\n\n    Expects a normalized path from `_normalize_path` (no trailing slash except root).\n\n    Args:\n        files: Dictionary mapping file paths to file data\n        normalized_path: Normalized path from `_normalize_path` (e.g., \"/\", \"/dir\", \"/dir/file\")","sourceCodeStart":733,"sourceCodeEnd":769,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/backends/utils.py#L733-L769","documentation":"_normalize_path rejects empty or whitespace-only path strings. Since an empty string is ambiguous (root vs. mistake), it raises ValueError('Path cannot be empty') to force callers to be explicit, suggesting '/' for root.","triggerScenarios":"Calling _normalize_path with a whitespace-only string like '   ' (a None is coalesced to '/', but blank strings are not), typically reached via _glob_search_files or grep_matches_from_files when the path parameter is empty/blank.","commonSituations":"Glob or grep tool invoked with an empty 'path' parameter by an LLM agent; config values set to '' instead of '/' or a real directory; string manipulation stripping a path to nothing.","solutions":["Pass '/' explicitly if you mean the root.","Pass a real directory path instead of an empty string.","Coalesce blank values before calling: path = path.strip() or '/'.","Trim and validate agent-supplied paths before invoking glob/grep tools."],"exampleFix":"// before\nfiles = glob_search(pattern=\"*.py\", path=\"   \")\n// after\nfiles = glob_search(pattern=\"*.py\", path=(path or \"/\").strip() or \"/\")","handlingStrategy":"validation","validationCode":"def normalize_search_path(path: str | None) -> str:\n    return (path or \"/\").strip() or \"/\"","typeGuard":"def is_valid_search_path(path: str | None) -> bool:\n    return path is None or (isinstance(path, str) and path.strip() != \"\")","tryCatchPattern":"try:\n    results = grep_matches_from_files(pattern, path=user_path)\nexcept ValueError as exc:\n    if str(exc) == \"Path cannot be empty\":\n        results = grep_matches_from_files(pattern, path=\"/\")\n    else:\n        raise","preventionTips":["Coalesce None/empty/blank path values to '/' before calling glob or grep tools.","Sanitize tool inputs coming from LLM agents (strip whitespace, reject blanks).","Default the path parameter in your wrappers instead of forwarding raw agent input.","Add schema-level minimum-length validation for path parameters."],"tags":["validation","path"],"backgroundTag":"empty-path-argument","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}