langchain-ai/deepagents · error · MarketplaceError

Path is neither a file nor a directory: {path}

Error message

Path is neither a file nor a directory: {path}

What it means

After the existence, file, and directory checks, `_marketplace_source_from_path` raises this error if the resolved path is neither a regular file nor a directory (marketplace.py:227-230). In practice this catches special filesystem objects — sockets, FIFOs, device nodes, or broken symlinks whose target vanished after the `exists()` check — i.e. a rare TOCTOU or special-file situation.

Source

Thrown at libs/code/deepagents_code/plugins/marketplace.py:230

    msg = "Invalid marketplace source format. Try: owner/repo, https://..., or ./path"
    raise MarketplaceError(msg)


def _marketplace_source_from_path(value: str) -> MarketplaceSource:
    path = Path(value).expanduser().resolve()
    if not path.exists():
        msg = f"Path does not exist: {path}"
        raise MarketplaceError(msg)
    if path.is_file():
        if path.suffix != ".json":
            msg = f"File path must point to a .json marketplace file: {path}"
            raise MarketplaceError(msg)
        return LocalMarketplaceSource(source_type="file", value=str(path))
    if path.is_dir():
        return LocalMarketplaceSource(source_type="directory", value=str(path))
    msg = f"Path is neither a file nor a directory: {path}"
    raise MarketplaceError(msg)


def _root_for_marketplace_file(path: Path) -> Path:
    for relative in _MARKETPLACE_RELATIVE_PATHS:
        if (
            len(path.parts) >= len(relative.parts)
            and path.parts[-len(relative.parts) :] == relative.parts
        ):
            return path.parents[len(relative.parts) - 1]
    return path.parent


def _load_marketplace_file(path: Path) -> PluginMarketplace:
    root = _root_for_marketplace_file(path.expanduser().resolve())
    return _load_marketplace_from_path(root, path.expanduser().resolve())


def _run_git(args: list[str]) -> None:

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Point the source at a regular directory or a `.json` file instead of a special filesystem object.
  2. If a symlink is involved, verify its target exists and is a directory or JSON file (`ls -l`, `readlink -f`).
  3. Re-run the command if it was a transient race; the target may have been replaced.

Example fix

// before
add_marketplace_source("/var/run/my-agent.sock")
// after
add_marketplace_source("/home/me/plugin-marketplaces/official")
Defensive patterns

Strategy: validation

Validate before calling

import os
from pathlib import Path

def validate_regular_path(raw: str) -> str:
    p = Path(raw).expanduser().resolve()
    if not (os.path.isfile(p) or os.path.isdir(p)):
        raise ValueError(f"Not a regular file or directory: {p}")
    return raw

Type guard

import os
from pathlib import Path

def is_regular_file_or_dir(value: str) -> bool:
    p = Path(value).expanduser().resolve()
    return os.path.isfile(p) or os.path.isdir(p)

Try / catch

try:
    source = parse_marketplace_source(raw)
except MarketplaceError as exc:
    if "neither a file nor a directory" in str(exc):
        raise ValueError(f"{raw!r} is a special file (socket/FIFO/device); pass a directory or .json file") from exc
    raise

Prevention

When it happens

Trigger: `parse_marketplace_source('/path/to/a/socket')` or a FIFO/device path passed as a marketplace source; a symlink whose target was deleted between the `path.exists()` check and the `is_file()`/`is_dir()` checks; calling `add_marketplace_source` with such a path.

Common situations: Accidentally pointing at a Unix socket (e.g. a Docker or SSH agent socket); shell completion selecting a device node; a race where a symlink is replaced/deleted mid-command.

Related errors


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