You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] prepare-commit-msg hook blocks every commit on LLM latency with no overall timeout #271
The prepare-commit-msg hook runs buildProfile() + generateSuggestions() synchronously inside the git commit path. The hook has no overall deadline of its own — a slow or stalled provider delays every commit for up to the per-request timeout (30s, src/providers/request.ts:1), and a provider outage adds seconds of latency to each commit before degrading to a warning. To an end user, git commit appears to hang.
Give the hook a tight overall deadline (e.g. abort suggestion generation after a few seconds and leave the commit message unchanged), so provider slowness can never block a commit for the full 30s. Consider also skipping the LLM call entirely when the provider appears unreachable (fast health check) or when --no-verify semantics apply.
Impact
Every commit's latency is coupled to LLM provider health; a hung provider stalls all commits for up to 30s each.
Users who install the hook and later hit a provider outage perceive git itself as broken.
runPrepareCommitMsgHook() awaits buildProfile() and generateSuggestions() directly on the git commit path.
Provider non-streaming requests use the 30s DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS, so a slow/unreachable provider can make git commit appear hung.
The hook catches provider errors and continues, so the impact is primarily commit latency rather than a rejected commit.
There is a second timeout gap: fetchWithTimeout() clears its timer once response headers arrive, while non-streaming providers then await response.json(). A stalled response body can therefore exceed the nominal 30s timeout.
Recommended fix:
Add a small hook-specific overall deadline (e.g. 3–5s) with abort propagation through the provider request.
On timeout/failure, leave the commit message unchanged, clear pending hook state, warn, and allow the commit to proceed.
Keep the normal provider timeout for non-hook commands.
Add regression tests for a never-resolving hook request and for a response that stalls after headers.
A simple Promise.race() timeout without cancellation is not sufficient because the underlying provider request could continue after the hook returns.
Implemented the fix in PR #322: #322. The prepare-commit-msg path now has a 5s overall deadline with abort propagation, keeps provider timeouts active through non-streaming response-body reads, and leaves the commit message unchanged on timeout. Regression coverage was added for both a stalled hook request and a stalled response body.
Activity
404-Page-Found commentedon Sep 22, 2026
Triage update:
Confirmed on current
main:runPrepareCommitMsgHook()awaitsbuildProfile()andgenerateSuggestions()directly on thegit commitpath.DEFAULT_PROVIDER_REQUEST_TIMEOUT_MS, so a slow/unreachable provider can makegit commitappear hung.fetchWithTimeout()clears its timer once response headers arrive, while non-streaming providers then awaitresponse.json(). A stalled response body can therefore exceed the nominal 30s timeout.Recommended fix:
A simple
Promise.race()timeout without cancellation is not sufficient because the underlying provider request could continue after the hook returns.404-Page-Found commentedon Sep 22, 2026
Implemented the fix in PR #322: #322. The prepare-commit-msg path now has a 5s overall deadline with abort propagation, keeps provider timeouts active through non-streaming response-body reads, and leaves the commit message unchanged on timeout. Regression coverage was added for both a stalled hook request and a stalled response body.
fix: bound prepare-commit-msg hook latency (#271) (#322)