git-ecosystem/git-credential-manager · error · Trace2Exception

GPG executable does not exist with path

Error message

GPG executable does not exist with path '{gpgPath}'

What it means

GetGpgPath throws this Trace2Exception when an explicit GPG executable path (from GCM_GPG_PATH or the gpg setting) points to a file that does not exist or is not executable. GCM verifies the configured path and fails fast rather than letting `pass`/GPG fail later with an obscure error.

Solutions

  1. Correct GCM_GPG_PATH (env) or the gpg setting to the actual executable path (verify with `which gpg` / `where gpg`).
  2. Clear GCM_GPG_PATH and let GCM auto-locate gpg2/gpg on PATH.
  3. Install GnuPG if it is missing, or ensure the configured file has execute permission (chmod +x).

Example fix

// before
export GCM_GPG_PATH=/usr/local/bin/gpg
// after
export GCM_GPG_PATH=$(which gpg)   # e.g. /opt/homebrew/bin/gpg
Defensive patterns

Strategy: validation

Validate before calling

const fs = require('fs');
if (gpgPath && !fs.existsSync(gpgPath)) {
  console.warn(`GCM_GPG_PATH does not exist: ${gpgPath}`);
}

Prevention

When it happens

Trigger: GCM_GPG_PATH env var or credential.storeGpg/gpg config points to a non-existent or non-executable file; EnsureBackingStore -> ValidateGpgPass -> GetGpgPath resolves the setting and File.Exists/execution check fails.

Common situations: GPG installed via Homebrew/package manager at a path different from the configured one (e.g. /opt/homebrew/bin/gpg vs /usr/local/bin/gpg after macOS migration); typo in GCM_GPG_PATH; GPG removed during an upgrade.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11). Data as JSON: /api/errors/b8d1d87049f59449. Report an issue: GitHub.

Appendix: source

Thrown at src/Core/CredentialStore.cs:365

        }

        private string GetGpgPath()
        {
            string gpgPath;

            // Use the GCM_GPG_PATH environment variable if set
            if (_context.Environment.Variables.TryGetValue(Constants.EnvironmentVariables.GpgExecutablePath,
                out gpgPath))
            {
                if (_context.FileSystem.FileExists(gpgPath))
                {
                    _context.Trace.WriteLine($"Using Git executable from GCM_GPG_PATH: {gpgPath}");
                    return gpgPath;
                }

                var format = "GPG executable does not exist with path '{0}'";
                var message = string.Format(format, gpgPath);
                throw new Trace2Exception(_context.Trace2, message, format);
            }

            // If no explicit GPG path is specified, mimic the way `pass`
            // determines GPG dependency (use gpg2 if available, otherwise gpg)
            if (_context.Environment.TryLocateExecutable("gpg2", out string gpg2Path))
            {
                _context.Trace.WriteLine($"Using PATH-located GPG (gpg2) executable: {gpg2Path}");
                return gpg2Path;
            }

            gpgPath = _context.Environment.LocateExecutable("gpg");
            _context.Trace.WriteLine($"Using PATH-located GPG (gpg) executable: {gpgPath}");
            return gpgPath;
        }
    }
}

View on GitHub (pinned to e8ce762cd0)