Skip to content

feat(git): report actionable errors for system git credentials - #10741

Merged
CurryYangxx merged 4 commits into
developfrom
feat/git-system-credential-errors
Nov 13, 2026
Merged

CurryYangxx merged 4 commits into
developfrom
feat/git-system-credential-errors

Conversation

@CurryYangxx

@CurryYangxx CurryYangxx commented Nov 10, 2026 •

Copy link
Copy Markdown
Member

Stack: #10738 (approve/reject credential protocol) → #10739 (interactive sign-in UX) → #10741 (this PR). Depends on #10739; review only the diff against feat/git-system-credential-ux.

Problem

When System Git Credentials can't provide credentials, users only see "The operation was canceled" or a generic authentication error, with no hint of the cause. It could be any of these:

  • git is not installed or not on PATH
  • the credential helper has no credentials for the host
  • the server rejected the stored credentials

The logs didn't help either, because git credential ran with stdio: 'ignore' for stderr and its output was thrown away. Also, with no terminal attached, git credential fill could try to prompt on a TTY when nothing was stored.

What changed

sync/git/providers/native.ts

  • git credential stderr is captured (capped at 2000 chars). On a non-zero exit it is logged.
  • git credential now runs with GIT_TERMINAL_PROMPT=0. A missing credential fails right away with a clear message (... terminal prompts disabled) instead of trying to prompt.
  • If the repository directory doesn't exist, git credential runs without cwd (global/system config) instead of failing with ENOENT, which would otherwise be reported as "Git not found".
  • fill() returns a typed outcome (filled / stopped / failed + reason). If fill fails, onAuth returns { cancel: true } right away. It no longer retries the request with empty credentials, which could never succeed.
  • New onNativeCredentialError listener API and NativeCredentialError { host, reason, detail? }, with these reasons:
  • Concurrent git operations fail together, so the same host + reason is reported at most once every 5 s.
  • Background (non-interactive) operations, such as the periodic fetch from feat(git): interactive sign-in UX for native credentials #10739, don't report credential errors; the user is told on their next action.

main/git/git-ipc-handler.ts, main/ipc/electron.ts

  • GitIpcHandler forwards errors to all windows on the new main→renderer channel git.native-credential-error.

ui/renderer-listeners.ts

  • Shows a persistent warning toast for each reason, with the helper detail appended when there is one:
    • "Git not found"
    • "Couldn't get git credentials": the system git credential manager didn't provide credentials for the host; try again, or use an Access Token credential; to sign in from Insomnia, use Git Credential Manager. The wording is neutral because this is also reported when the user closes the credential manager's sign-in window, so it must not tell GCM users to install GCM.
    • "Git credentials rejected"
  • At most one toast per host + reason while it is still open (checked against queue.visibleToasts), so repeated failures don't stack persistent toasts.

Design decision: still end with cancel instead of throwing a custom error

The git operation still ends with { cancel: true }, which isomorphic-git turns into a UserCanceledError. We send the specific reason on a side channel instead of throwing a custom error from onAuth.

The existing UI (clone form, push/pull dropdown, staging modal) maps UserCanceledError → AuthenticationRequiredError to start its re-authenticate flow. A custom error would downgrade all of these to a generic "Failed to fetch from remote".

Trade-off: the existing generic auth toast (e.g. "Push failed — Connection has expired. Re-authenticate") still appears next to the new specific toast. Its Re-authenticate link doesn't help with System Git Credentials. A follow-up could merge the two.

Notes

  • GIT_TERMINAL_PROMPT=0 and GCM. Based on GCM's logic, this setting only disables terminal prompts. Browser OAuth and GUI prompts in a desktop session are controlled by a separate setting, so GCM sign-in should still work. This has not been verified manually yet (see test plan).
  • Out of scope, deferred to a later release:
    • Resolving git from the login-shell PATH.
    • Detecting missing Xcode Command Line Tools on macOS. Until then, on a Mac without CLT the /usr/bin/git shim can still open the CLT install dialog.

Testing

Done:

  • Unit tests in native.test.ts: stderr detail is surfaced, git-not-found on spawn error, reports are deduped, rejected after the retry, GIT_TERMINAL_PROMPT=0 is set in the spawn env, missing repository directory runs without cwd, no credential errors for background operations, a synchronous spawn failure cancels
  • Follow-up fixes (toast dedupe, missing cwd, neutral wording, background silence) from a code review of the stack
  • npm run type-check and npm run lint pass

Manual test plan (not yet tested in the app):

  • Non-GCM helper (e.g. osxkeychain) with no credentials for the host → "Couldn't get git credentials" toast that includes the helper detail
  • Bad credential rejected twice → "Git credentials rejected" toast
  • git not on PATH → "Git not found" toast
  • GCM with cleared credentials → browser login still opens with GIT_TERMINAL_PROMPT=0; closing the sign-in window → neutral "Couldn't get git credentials" toast
  • Repeated failures for the same host → only one toast while it is open

Stack created with GitHub Stacks CLI • Give Feedback 💬

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved issues allow unbounded stderr memory growth, duplicate queued credential warnings, and misleading installation advice when Git fails to start.

3 open issues
What changed in this PR

Adds actionable System Git Credentials errors to Insomnia’s existing native Git sign-in flow, forwarding failure reasons to the UI while preserving authentication cancellation behavior.

Changes:

  • Classifies credential failures, captures helper diagnostics, and handles missing repository directories.
  • Forwards errors through IPC and displays persistent warnings with host/reason deduplication, while keeping background operations quiet.
  • Extends unit tests for failure reporting, process options, and cancellation.
File Description
packages/​insomnia/​src/​ui/​renderer-listeners.ts Displays reason-specific credential warnings and deduplicates toasts.
packages/​insomnia/​src/​sync/​git/​providers/​native.ts Classifies failures, captures stderr, and emits credential errors.
packages/​insomnia/​src/​sync/​git/​providers/​__tests__/​native.test.ts Tests diagnostics, deduplication, cancellation, and background behavior.
packages/​insomnia/​src/​main/​ipc/​electron.ts Declares the credential-error IPC channel.
packages/​insomnia/​src/​main/​git/​git-ipc-handler.ts Broadcasts credential errors to renderer windows.

Review effort: Balanced

@CurryYangxx
CurryYangxx force-pushed the feat/git-system-credential-errors branch 3 times, most recently from ac65d39 to 304b02b Compare November 11, 2026 09:37
@CurryYangxx
CurryYangxx requested a balanced review from Copilot November 11, 2026 09:41
@CurryYangxx
CurryYangxx marked this pull request as ready for review November 11, 2026 09:42
@github-actions

github-actions Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

❌ KSAI Review: Failed

The review did not complete (no-result). Nothing was salvaged to post as a review. What it spent is below; see the workflow run for details


Run report (federated) · 0 paid runs · cost not recoverable from a partial log
# Engine Result Model
1 opencode `` glm-5.3-flash/max

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The credential fallback can use an unrelated checkout’s credential store, and toast deduplication can create duplicate persistent warnings when the original warning is queued but not visible.

1 open issue
3 resolved since last review

Review effort: Balanced

@CurryYangxx
CurryYangxx force-pushed the feat/git-system-credential-errors branch 2 times, most recently from b651c77 to 5d535ab Compare November 12, 2026 06:21
@yaoweiprc

Copy link
Copy Markdown
Contributor

Manual test results (Windows 11 + Git Credential Manager)

Tested the top of the stack (5d535abdf, includes #10738, #10739 and this PR) in the running app against a real Azure DevOps repo, plus a logging credential helper injected into the Insomnia process via GIT_CONFIG_COUNT/GIT_CONFIG_KEY_* to simulate failures without touching the real credential store. Windows 11, Git 2.50.1, GCM 2.6.1.

Scenario Result
Unit tests (native, git-callbacks, github, gitlab; 49 tests) Pass
git-vcs.test.ts (3 failures in undoPendingChanges / buildManualResolutionFromTrees) Same 3 fail on develop, unrelated
tsc --noEmit (insomnia package) Pass, 0 errors
ESLint on the 17 files changed by the stack Pass
Real Azure sign-in via GCM One login, then get → store. The next operation reuses the credential (get ~35 ms), no new login
Bad token, then real credential get(bad) → erase → get(real) → store, branches load, no toast
Helper always returns a bad token get → erase → get → erase: exactly one retry, then "Git credentials rejected"
Cancel sign-in with a slow helper Whole tree (git → sh → sh → sh → PING.EXE) gone within 3 s
Fill timeout (5 min, real wait) "Git sign-in timed out" at exactly 5:00, processes cleaned up
git not on PATH "Git not found" toast
Repeated failure for the same host Helper called twice, only one toast
Real clone Succeeds (get → store)
Periodic background fetch with no stored credential Helper called once with GCM_INTERACTIVE=never, no sign-in, no toast
Closing the GCM sign-in window Waiting toast replaced by "Couldn't get git credentials", no leftover processes

Not covered: concurrent-fill dedupe in the UI (unit tests only), push/pull (the test repo has no Insomnia files), macOS/Linux process-group cleanup, and Entra ID (non-personal) Azure accounts.

Issue: the toast detail hides the credential helper's own error

When a helper fails to provide credentials, the detail shown in the "Couldn't get git credentials" toast is always git's generic fallback message, never the helper's message.

Repro

  1. Use a helper that writes helper: no credentials for dev.azure.com to stderr and exits 1 (or prints nothing).
  2. Trigger a branch list/clone with System Git Credentials.

Actual
The toast ends with (fatal: could not read Username for 'https://dev.azure.com/…': terminal prompts disabled).

Why
After the helper fails, git falls back to prompting and, with GIT_TERMINAL_PROMPT=0, appends that fatal: line. Running git credential fill directly with the same helper prints both lines, the helper's first and git's last:

helper: no credentials for example.org
fatal: could not read Username for 'https://example.org': terminal prompts disabled

summarizeStderr takes the last non-empty line, so it always returns git's line. The PR description says the detail is the last line of the helper's stderr, but in practice it is never the helper's line.

Impact

  • The detail carries no information about the real cause.
  • It is misleading when the user closes the GCM sign-in window: the toast mentions disabled terminal prompts, which has nothing to do with what happened.

Suggestion
Prefer the first meaningful stderr line and skip git's own fatal: could not read … fallback line, for example by filtering it out before picking a line, or by dropping the detail when only that line is present.

@CurryYangxx
CurryYangxx force-pushed the feat/git-system-credential-errors branch 3 times, most recently from 21f0176 to cff2f5a Compare November 13, 2026 03:14
Base automatically changed from feat/git-system-credential-ux to develop November 13, 2026 03:27
@CurryYangxx
CurryYangxx force-pushed the feat/git-system-credential-errors branch 2 times, most recently from 1af1660 to e511b9b Compare November 13, 2026 03:41
CurryYangxx and others added 4 commits November 13, 2026 16:16
When System Git Credentials cannot provide credentials, the git operation
still fails with the existing authentication error, so current UI flows keep
working, and the reason is now reported to the UI as a warning toast:

- git could not be started (not installed / not on PATH)
- the credential helper has no credentials for the host, including the last
  line of the helper's stderr
- the server rejected the helper's credentials after a retry

Also:
- run `git credential` with GIT_TERMINAL_PROMPT=0 so a missing credential
  fails fast with a clear message instead of trying to prompt on a terminal
- capture and log the helper's stderr on failure
- cancel instead of retrying the request without credentials when fill fails
- report a failure shared by concurrent requests only once

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- keep at most one credential error toast per host and reason while it is
  open, so repeated failures do not stack persistent toasts
- run git credential without cwd when the repository directory does not
  exist, instead of reporting "Git not found" for the resulting ENOENT
- word the "no credentials" error neutrally: it is also reported when the
  user closes the credential manager's sign-in, so it no longer tells users
  who already have Git Credential Manager to install it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…m git missing

Keep only the tail of the credential helper's stderr while it runs instead of
buffering all of it. Report "git not found" only for ENOENT; other spawn
failures (e.g. EACCES) now get their own message with the error details
instead of advice to install git.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@CurryYangxx
CurryYangxx force-pushed the feat/git-system-credential-errors branch from e0e8952 to 93d3710 Compare November 13, 2026 08:16
@CurryYangxx
CurryYangxx enabled stacked auto-merge (squash) November 13, 2026 08:16
@CurryYangxx
CurryYangxx merged commit 3f15346 into develop Nov 13, 2026
25 checks passed
@CurryYangxx
CurryYangxx deleted the feat/git-system-credential-errors branch November 13, 2026 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants