{"record":{"id":"fbc8dc084e2a5dc6","repo":"langchain-ai/deepagents","slug":"failed-to-run-git-redact-urls-in-text-str-exc","errorCode":null,"errorMessage":"Failed to run git: {redact_urls_in_text(str(exc))}","messagePattern":"Failed to run git: (.+?)","errorType":"exception","errorClass":"MarketplaceError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/plugins/marketplace.py","lineNumber":271,"sourceCode":"    # Inherit normal Git configuration, but disable credential prompts because\n    # this subprocess has no interactive input.\n    env = {\n        **os.environ,\n        \"GIT_TERMINAL_PROMPT\": \"0\",\n        \"GIT_ASKPASS\": \"\",\n    }\n    try:\n        result = subprocess.run(  # noqa: S603  # Fixed git executable, no shell.\n            [git_path, *args],\n            check=False,\n            capture_output=True,\n            env=env,\n            text=True,\n            timeout=_GIT_TIMEOUT_SECONDS,\n        )\n    except (OSError, subprocess.TimeoutExpired) as exc:\n        msg = f\"Failed to run git: {redact_urls_in_text(str(exc))}\"\n        raise MarketplaceError(msg) from exc\n    if result.returncode != 0:\n        detail = result.stderr.strip() or result.stdout.strip() or \"unknown git error\"\n        msg = f\"Git command failed: {redact_urls_in_text(detail)}\"\n        raise MarketplaceError(msg)\n\n\ndef _clone_repository_to_cache(\n    source: RepositoryMarketplaceSource,\n    git_url: str,\n    *,\n    cache_key: str,\n    validate: Callable[[Path], None] | None = None,\n) -> Path:\n    cache_path = ensure_marketplace_cache_dir() / (\n        f\"repository-{opaque_cache_key(cache_key)}\"\n    )\n    temp_path = Path(\n        tempfile.mkdtemp(prefix=f\".{cache_path.name}.\", dir=cache_path.parent)","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/plugins/marketplace.py#L253-L289","documentation":"`_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.","triggerScenarios":"`_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.","commonSituations":"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.","solutions":["Retry the add command — transient network slowness may have exceeded the 120s timeout.","Check the git binary is executable and runnable (`git --version`) to rule out `OSError` from permissions or a broken install.","Pre-clone the repository manually with git (so you can supply credentials interactively), then register the local checkout as a path marketplace.","Disable hanging credential helpers/prompts for non-interactive use (`git config --global credential.helper ''` or use a token-based remote).","For very large repos, do a shallow clone locally first and point the marketplace at the local path."],"exampleFix":"// before (hung credential prompt in CI, 120s timeout)\nadd_marketplace_source(\"git@github.com:owner/private-marketplace.git\")\n// after (pre-clone with credentials, then use local path)\nsubprocess.run([\"git\", \"clone\", \"git@github.com:owner/private-marketplace.git\"])\nadd_marketplace_source(\"./private-marketplace\")","handlingStrategy":"retry","validationCode":"import subprocess\n\ndef git_is_runnable() -> bool:\n    try:\n        return subprocess.run([\"git\", \"--version\"], capture_output=True, timeout=10).returncode == 0\n    except (OSError, subprocess.TimeoutExpired):\n        return False","typeGuard":"import shutil, subprocess\n\ndef git_binary_healthy() -> bool:\n    git = shutil.which(\"git\")\n    if git is None:\n        return False\n    try:\n        return subprocess.run([git, \"--version\"], capture_output=True, timeout=10).returncode == 0\n    except (OSError, subprocess.TimeoutExpired):\n        return False","tryCatchPattern":"import time\nfor attempt in range(3):\n    try:\n        add_marketplace_source(repo_source)\n        break\n    except MarketplaceError as exc:\n        if \"Failed to run git\" not in str(exc) or attempt == 2:\n            raise\n        time.sleep(2 ** attempt)  # back off on timeout/transient exec failures","preventionTips":["Pre-clone large repos manually (shallow clone) and register the local path to avoid the 120s timeout.","Ensure no credential helper blocks without a TTY; use token-based remotes in non-interactive environments.","Check the git binary is executable and not on a noexec mount.","Retry with backoff for slow-network timeout cases."],"tags":["git","subprocess","timeout","network"],"backgroundTag":"git-subprocess-failed","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}