{"record":{"id":"337c86fe8f47b291","repo":"git-ecosystem/git-credential-manager","slug":"failed-to-start-gpg","errorCode":null,"errorMessage":"Failed to start gpg.","messagePattern":"Failed to start gpg\\.","errorType":"exception","errorClass":"Trace2Exception","httpStatus":null,"severity":"error","filePath":"src/Core/Gpg.cs","lineNumber":49,"sourceCode":"\n        public string DecryptFile(string path)\n        {\n            var psi = new ProcessStartInfo(_gpgPath, $\"--batch --decrypt \\\"{path}\\\"\")\n            {\n                UseShellExecute = false,\n                RedirectStandardOutput = true,\n                // Suppress verbose decryption messages\n                // Ok to redirect stderr for non-Git-related processes\n                RedirectStandardError = true,\n            };\n\n            PrepareEnvironment(psi);\n\n            using (var gpg = _processManager.CreateProcess(psi))\n            {\n                if (!gpg.Start(Trace2ProcessClass.Other))\n                {\n                    throw new Trace2Exception(_trace2, \"Failed to start gpg.\");\n                }\n\n                gpg.WaitForExit();\n\n                if (gpg.ExitCode != 0)\n                {\n                    string stdout = gpg.StandardOutput.ReadToEnd();\n                    string stderr = gpg.StandardError.ReadToEnd();\n                    var format = \"Failed to decrypt file '{0}' with gpg. exit={1}, out={2}, err={3}\";\n                    var message = string.Format(format, path, gpg.ExitCode, stdout, stderr);\n                    throw new Trace2Exception(_trace2, message, format);\n                }\n\n                return gpg.StandardOutput.ReadToEnd();\n            }\n        }\n\n        public void EncryptFile(string path, string gpgId, string contents)","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Core/Gpg.cs#L31-L67","documentation":"Gpg.DecryptFile launches the external gpg executable via the configured IProcessManager to decrypt a file. If the process fails to start at all (gpg.Start returns false), it throws Trace2Exception with this message. This is an environment problem, not a data problem.","triggerScenarios":"Calling DecryptFile when the gpg binary is not installed, not on PATH, the configured GpgPath/program path is wrong, or the OS refuses to spawn the process.","commonSituations":"Clean machines or CI containers without GnuPG installed; incorrect gpg configuration path in settings; PATH differences between dev shell and service environment.","solutions":["Install GnuPG (gpg) and verify `gpg --version` works in the same environment the app runs in.","Check the configured gpg executable path in settings (e.g. credential.gpg path config) and correct it.","Ensure PATH includes the gpg install directory for the service/account running the app.","Catch the Trace2Exception and surface an actionable 'install/configure gpg' message to the user."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-flight check before calling DecryptFile\nbool gpgAvailable = FindExecutable(\"gpg\") is not null; // or resolve the configured path","typeGuard":null,"tryCatchPattern":"try { plaintext = gpg.DecryptFile(path); }\ncatch (Trace2Exception ex) when (ex.Message == \"Failed to start gpg.\")\n{ throw new InvalidOperationException(\"gpg is not installed or not on PATH; install GnuPG or fix the configured gpg path.\", ex); }","preventionTips":["Install GnuPG wherever the app runs, including CI images.","Verify gpg availability at startup and fail fast with an actionable message.","Pin the gpg path in configuration instead of relying on PATH."],"tags":["gpg","process-start","external-dependency","environment"],"backgroundTag":"missing-dependency","analyzedSha":"e8ce762cd04b4100ae637b5fbf39ef9d0a96561e","analyzedAt":"2026-09-11T17:15:08.753Z","contentChangedAt":"2026-09-11T17:15:08.753Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}