{"record":{"id":"37216fcd7acc7ea8","repo":"can1357/oh-my-pi","slug":"git-fn-name-timed-out","errorCode":null,"errorMessage":"git {fn.__name__} timed out","messagePattern":"git (.+?) timed out","errorType":"http","errorClass":"HTTPException","httpStatus":504,"severity":"error","filePath":"python/robomp/src/proxy/server.py","lineNumber":827,"sourceCode":"    # event loop until the subprocess returns; a hung git would freeze the\n    # whole proxy. We bridge with `asyncio.to_thread` (work on a threadpool\n    # worker) wrapped in `asyncio.wait_for` (hard wall-clock cap, returns\n    # 504 on timeout). The subprocess itself can outlive the timeout — a\n    # proper subprocess.kill plumbing would have to live inside\n    # `git_ops._run_git`; flagged for follow-up.\n\n    async def _run_git_op(fn, *args, **kwargs):  # type: ignore[no-untyped-def]\n        try:\n            return await asyncio.wait_for(\n                asyncio.to_thread(fn, *args, **kwargs),\n                timeout=settings.gh_proxy_git_timeout_seconds,\n            )\n        except TimeoutError as exc:\n            log.warning(\n                \"gh-proxy: git op exceeded timeout\",\n                extra={\"op\": fn.__name__, \"timeout\": settings.gh_proxy_git_timeout_seconds},\n            )\n            raise HTTPException(504, f\"git {fn.__name__} timed out\") from exc\n\n    @app.post(\"/gh/v1/git/clone\")\n    async def git_clone_endpoint(request: Request) -> JSONResponse:\n        data = await _json_body(request)\n        repo = _require_str(data.get(\"repo\"), \"repo\")\n        clone_url = _require_str(data.get(\"clone_url\"), \"clone_url\")\n        default_branch = _require_str(data.get(\"default_branch\"), \"default_branch\")\n        remote = _clone_remote_auth(clone_url, repo, _resolve_token(settings))\n        target = _pool_dir(settings, repo)\n        try:\n            await _run_git_op(\n                git_clone,\n                target,\n                clone_url=remote.url,\n                default_branch=default_branch,\n                token=remote.token,\n                auth_url=remote.auth_url,\n            )","sourceCodeStart":809,"sourceCodeEnd":845,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/robomp/src/proxy/server.py#L809-L845","documentation":"`_run_git_op` wraps proxy-side git operations (clone, fetch, fetch_ref, fetch_pr_head, push, push_release) with a timeout from `settings.gh_proxy_git_timeout_seconds`. When the git subprocess exceeds that budget, the proxy logs a warning and returns HTTP 504 with this message. It means the git operation did not complete in the configured time, not that it failed for a git-level reason.","triggerScenarios":"Any POST to /gh/v1/git/clone, git/fetch, git/fetch_ref, git/fetch_pr_head, git/push, or git/push_release where the underlying git command (e.g. cloning a huge repo over a slow network, or a push of a large release) takes longer than `gh_proxy_git_timeout_seconds`.","commonSituations":"Cloning large monorepos or repos with big LFS/history, slow or flaky network between proxy and github.com, GitHub slowness, or the timeout setting tuned too aggressively low for your repo sizes.","solutions":["Increase `settings.gh_proxy_git_timeout_seconds` to a value that accommodates your largest repos/network","Retry the operation — transient slowness often succeeds on a second attempt","Reduce data transferred: shallow clone / narrower ref fetches where the API allows","Check network path between proxy host and GitHub (proxy, DNS, bandwidth) for bottlenecks"],"exampleFix":"# before\ngh_proxy_git_timeout_seconds = 60\n# after\ngh_proxy_git_timeout_seconds = 600","handlingStrategy":"retry","validationCode":"// estimate required timeout from repo size / network before calling\nconst minTimeoutSeconds = 300; // pick based on your largest repo\nif (settings.gh_proxy_git_timeout_seconds < minTimeoutSeconds) {\n  throw new Error(`git timeout ${settings.gh_proxy_git_timeout_seconds}s too low for this repo`);\n}","typeGuard":null,"tryCatchPattern":"try:\n    proxy.git_clone(repo=repo, clone_url=url)\nexcept HTTPError as e:\n    if e.response.status_code == 504 and \"timed out\" in e.response.text:\n        time.sleep(backoff)\n        retry_with_longer_budget()  # or raise actionable error about repo size/network\n    else:\n        raise","preventionTips":["Set gh_proxy_git_timeout_seconds generously for large repos","Prefer shallow/narrow fetches to reduce transfer time","Monitor proxy logs for repeated timeouts per repo to tune the budget","Check network path to GitHub (proxies, DNS, bandwidth) when timeouts cluster"],"tags":["git","timeout","network","http-504"],"backgroundTag":"operation-timed-out","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}