{"record":{"id":"869272b2338f44d0","repo":"can1357/oh-my-pi","slug":"git-timed-out-after-effective-timeout-0f-s","errorCode":null,"errorMessage":"git timed out after {effective_timeout:.0f}s: {' '.join(_redacted_cmd(cmd))}","messagePattern":"git timed out after (.+?)s: (.+?)","errorType":"exception","errorClass":"GitCommandError","httpStatus":null,"severity":"error","filePath":"python/robomp/src/git_ops.py","lineNumber":277,"sourceCode":"    try:\n        proc = subprocess.run(\n            cmd,\n            cwd=str(cwd) if cwd else None,\n            env=env,\n            check=False,\n            capture_output=True,\n            text=True,\n            timeout=effective_timeout,\n            **subprocess_kwargs,\n        )\n    except subprocess.TimeoutExpired as exc:\n        # `subprocess.run` already kills the direct child when the timeout\n        # fires, but we explicitly re-raise as `GitCommandError` so callers\n        # don't have to special-case `TimeoutExpired` alongside the regular\n        # non-zero-exit error path. 124 mirrors GNU `timeout`.\n        stdout = redact_credentials(exc.stdout or \"\") if isinstance(exc.stdout, str) else \"\"\n        stderr_msg = f\"git timed out after {effective_timeout:.0f}s: {' '.join(_redacted_cmd(cmd))}\"\n        raise GitCommandError(cmd, 124, stdout, stderr_msg) from exc\n    if proc.stdout:\n        proc.stdout = redact_credentials(proc.stdout)\n    if proc.stderr:\n        proc.stderr = redact_credentials(proc.stderr)\n    return proc\n\n\ndef _check(proc: subprocess.CompletedProcess[str], cmd: list[str]) -> subprocess.CompletedProcess[str]:\n    if proc.returncode != 0:\n        raise GitCommandError(cmd, proc.returncode, proc.stdout, proc.stderr)\n    return proc\n\n\ndef _git_dir(repo_dir: Path) -> Path | None:\n    dot_git = repo_dir / \".git\"\n    if dot_git.is_dir():\n        return dot_git\n    if dot_git.is_file():","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/robomp/src/git_ops.py#L259-L295","documentation":"`_run_git` wraps `subprocess.TimeoutExpired` into a `GitCommandError` with exit code 124 (mirroring GNU timeout) and a message stating how long git was allowed to run plus the credential-redacted command. The library raises this so callers only need to handle one git-failure type instead of also special-casing timeouts; the direct child is already killed when the timeout fires.","triggerScenarios":"Any git operation routed through `_run_git` (clone, fetch_prune, fetch_ref, _worktrees_holding_refs, _remove_worktrees, _delete_bad_refs) exceeding `effective_timeout` — typically a slow/blocked network fetch, a huge clone, or git hanging on a credential prompt.","commonSituations":"Flaky or throttled network to the remote, git waiting on an interactive username/password prompt in a non-interactive environment (no GIT_TERMINAL_PROMPT=0), proxy transport stalls, very large repos on slow disks.","solutions":["Retry the command — timeouts are often transient network issues","Increase the configured timeout (e.g. ROBOMP_GH_PROXY_GIT_TIMEOUT_SECONDS) if the repo legitimately needs longer","Ensure git never blocks on prompts: set GIT_TERMINAL_PROMPT=0 and configure a credential helper or token in the URL","Check connectivity to the remote / proxy before retrying"],"exampleFix":"// before\n_run_git([\"clone\", url, dest])  # default timeout too short for big repo\n// after\n_run_git([\"clone\", url, dest], timeout=600)  # and export GIT_TERMINAL_PROMPT=0","handlingStrategy":"retry","validationCode":"import shutil, os\nif not shutil.which(\"git\"): raise RuntimeError(\"git not installed\")\nos.environ.setdefault(\"GIT_TERMINAL_PROMPT\", \"0\")  # prevent hangs on auth prompts","typeGuard":null,"tryCatchPattern":"from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_exponential\n@retry(retry=retry_if_exception_type(GitCommandError), stop=stop_after_attempt(3), wait=wait_exponential(min=2))\ndef do_clone(url, dest):\n    clone(url, dest)","preventionTips":["Set GIT_TERMINAL_PROMPT=0 and configure credential helpers so git never blocks interactively","Size timeouts to the largest expected repo/fetch, not the average","Prefer shallow/partial clones to keep fetches fast","Monitor network path to the remote/proxy; alert on latency growth"],"tags":["git","timeout","network","subprocess"],"backgroundTag":"git-command-timeout","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}