langchain-ai/deepagents · error · FileExistsError

Refusing to remove non-socket external event path: {path}

Error message

Refusing to remove non-socket external event path: {path}

What it means

`_unlink_existing_socket` cleans up a stale Unix socket path before the external event bus binds it. To protect against deleting unrelated files, it stats the path with symlinks not followed and refuses to unlink anything that is not a socket. It raises `FileExistsError` so the caller can report that the configured path collides with a non-socket filesystem entry rather than silently removing it.

Source

Thrown at libs/code/deepagents_code/event_bus.py:355

    base = Path(root) if root else Path(tempfile.gettempdir())
    return base / "deepagents" / f"events-{os.getpid()}.sock"


def _unlink_existing_socket(path: Path) -> None:
    """Remove a stale Unix socket without touching other filesystem entries.

    Args:
        path: Candidate socket path to remove.

    Raises:
        FileNotFoundError: If `path` does not exist.
        FileExistsError: If `path` exists but is not a Unix socket.
        OSError: If the entry exists but cannot be removed.
    """  # noqa: DOC502  # FileNotFoundError/OSError propagate from stat/unlink
    info = path.stat(follow_symlinks=False)
    if not stat.S_ISSOCK(info.st_mode):
        msg = f"Refusing to remove non-socket external event path: {path}"
        raise FileExistsError(msg)
    path.unlink()


def decode_external_event(data: bytes, *, source: str) -> ExternalEvent:
    """Decode one newline-delimited JSON external event.

    Args:
        data: Raw JSON line.
        source: Transport-specific source label attached to the event.

    Returns:
        Parsed external event.

    Raises:
        TypeError: If the envelope is not a JSON object.
        ValueError: If any envelope field is missing, of the wrong type, or
            otherwise invalid.
    """

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Inspect the path in the message and delete or rename the non-socket entry manually, then retry `start()`.
  2. If a custom socket path is configured, change it to an unused location instead of reusing an existing file path.
  3. If the entry is a symlink, replace the symlink target with an actual Unix socket or remove the symlink.
  4. Check nothing else (another process) owns that path; pick a per-process path or different XDG_RUNTIME_DIR.

Example fix

# before
# socket path occupied by a stale regular file
rm /tmp/deepagents/events-1234.sock   # actually a regular file

# after
# path removed; bus can bind the socket
Defensive patterns

Strategy: validation

Validate before calling

import stat
from pathlib import Path

def socket_path_is_clear(path: Path) -> bool:
    try:
        mode = path.stat(follow_symlinks=False).st_mode
    except FileNotFoundError:
        return True
    return stat.S_ISSOCK(mode)

# remove or relocate non-socket entries before start()
if not socket_path_is_clear(path):
    path.unlink(missing_ok=True) if path.is_file() or path.is_symlink() else None

Type guard

def is_unix_socket(path: Path) -> bool:
    try:
        return stat.S_ISSOCK(path.stat(follow_symlinks=False).st_mode)
    except FileNotFoundError:
        return False

Try / catch

try:
    bus.start()
except FileExistsError as exc:
    logger.error("socket path occupied by non-socket entry: %s", exc)
    # pick a different path or remove the entry manually

Prevention

When it happens

Trigger: Calling `start()` or `stop()` (or `_cleanup_external_event_source_sync`) when the socket path (default `$(XDG_RUNTIME_DIR or /tmp)/deepagents/events-<pid>.sock`, or a custom path) exists but is a regular file, directory, FIFO, or symlink to a non-socket, e.g. leftover from a config change or created by another process.

Common situations: A user pre-created the `deepagents/` directory with a placeholder file at the socket path; a previous crash left a regular file where a socket used to be; the custom socket path points at a log or PID file; a symlinked path resolves to a plain file.

Related errors


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