langchain-ai/deepagents · error · MarketplaceError

Failed to run git: {redact_urls_in_text(str(exc))}

Error message

Failed to run git: {redact_urls_in_text(str(exc))}

What it means

`_run_git` wraps `OSError` and `subprocess.TimeoutExpired` from the git subprocess and re-raises them as this `MarketplaceError`, with the exception text passed through `redact_urls_in_text` so embedded HTTP credentials are masked (marketplace.py:269-271). It means the git process could not be started or did not finish within the 120-second timeout — not that git reported a failure itself.

Source

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

    # Inherit normal Git configuration, but disable credential prompts because
    # this subprocess has no interactive input.
    env = {
        **os.environ,
        "GIT_TERMINAL_PROMPT": "0",
        "GIT_ASKPASS": "",
    }
    try:
        result = subprocess.run(  # noqa: S603  # Fixed git executable, no shell.
            [git_path, *args],
            check=False,
            capture_output=True,
            env=env,
            text=True,
            timeout=_GIT_TIMEOUT_SECONDS,
        )
    except (OSError, subprocess.TimeoutExpired) as exc:
        msg = f"Failed to run git: {redact_urls_in_text(str(exc))}"
        raise MarketplaceError(msg) from exc
    if result.returncode != 0:
        detail = result.stderr.strip() or result.stdout.strip() or "unknown git error"
        msg = f"Git command failed: {redact_urls_in_text(detail)}"
        raise MarketplaceError(msg)


def _clone_repository_to_cache(
    source: RepositoryMarketplaceSource,
    git_url: str,
    *,
    cache_key: str,
    validate: Callable[[Path], None] | None = None,
) -> Path:
    cache_path = ensure_marketplace_cache_dir() / (
        f"repository-{opaque_cache_key(cache_key)}"
    )
    temp_path = Path(
        tempfile.mkdtemp(prefix=f".{cache_path.name}.", dir=cache_path.parent)

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Retry the add command — transient network slowness may have exceeded the 120s timeout.
  2. Check the git binary is executable and runnable (`git --version`) to rule out `OSError` from permissions or a broken install.
  3. Pre-clone the repository manually with git (so you can supply credentials interactively), then register the local checkout as a path marketplace.
  4. Disable hanging credential helpers/prompts for non-interactive use (`git config --global credential.helper ''` or use a token-based remote).
  5. For very large repos, do a shallow clone locally first and point the marketplace at the local path.

Example fix

// before (hung credential prompt in CI, 120s timeout)
add_marketplace_source("git@github.com:owner/private-marketplace.git")
// after (pre-clone with credentials, then use local path)
subprocess.run(["git", "clone", "git@github.com:owner/private-marketplace.git"])
add_marketplace_source("./private-marketplace")
Defensive patterns

Strategy: retry

Validate before calling

import subprocess

def git_is_runnable() -> bool:
    try:
        return subprocess.run(["git", "--version"], capture_output=True, timeout=10).returncode == 0
    except (OSError, subprocess.TimeoutExpired):
        return False

Type guard

import shutil, subprocess

def git_binary_healthy() -> bool:
    git = shutil.which("git")
    if git is None:
        return False
    try:
        return subprocess.run([git, "--version"], capture_output=True, timeout=10).returncode == 0
    except (OSError, subprocess.TimeoutExpired):
        return False

Try / catch

import time
for attempt in range(3):
    try:
        add_marketplace_source(repo_source)
        break
    except MarketplaceError as exc:
        if "Failed to run git" not in str(exc) or attempt == 2:
            raise
        time.sleep(2 ** attempt)  # back off on timeout/transient exec failures

Prevention

When it happens

Trigger: `_clone_repository_to_cache` invokes `_run_git` and: the git binary cannot be executed (`PermissionError`, missing shared libs → `OSError`); the clone takes longer than `_GIT_TIMEOUT_SECONDS = 120` (slow network, huge repo, hung credential helper) → `TimeoutExpired`; resource exhaustion preventing fork/exec.

Common situations: Cloning a very large monorepo marketplace over a slow VPN; a credential helper (e.g. `git-credential-manager`) hanging without a TTY; noexec-mounted filesystems or wrong permissions on the git binary; corporate proxies making the connection hang until timeout.

Related errors


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