unoplatform/uno · critical · InvalidOperationException

Failed to start git process.

Error message

Failed to start git process.

What it means

RunGit launches the `git` binary as a child process with UseShellExecute=false. Process.Start returns null when the OS cannot resolve or launch the executable, which this method treats as a fatal InvalidOperationException. This is the FontFallbackPreprocessor's only way to clone/fetch font fallback repos, so a null process aborts the whole preprocessing build step.

Source

Thrown at src/FontFallbackPreprocessor/Program.cs:794

	private static void CheckoutBranch(string repoPath, string branch)
	{
		RunGit($"-C \"{repoPath}\" checkout {branch}");
		RunGit($"-C \"{repoPath}\" reset --hard origin/{branch}");
	}

	private static void RunGit(string arguments)
	{
		var processStart = new ProcessStartInfo
		{
			FileName = "git",
			Arguments = arguments,
			CreateNoWindow = true,
			UseShellExecute = false,
			RedirectStandardError = true,
			RedirectStandardOutput = true
		};

		using var process = Process.Start(processStart) ?? throw new InvalidOperationException("Failed to start git process.");
		process.WaitForExit();

		if (process.ExitCode != 0)
		{
			var error = process.StandardError.ReadToEnd();
			throw new InvalidOperationException($"git {arguments} failed: {error}");
		}
	}
}

View on GitHub (pinned to 0418340488)

Solutions

  1. Install git and confirm `git --version` succeeds from the same shell that runs the build.
  2. Verify git resolves on PATH: `where git` (Windows) or `which git` (Linux/macOS) from the build's working directory.
  3. If PATH isn't inherited, set it explicitly or pass the absolute path by editing FileName to the full git binary location.
  4. In Docker/CI images, add git to the image (e.g. `apt-get install -y git` or `apk add git`).

Example fix

// before
FileName = "git",
UseShellExecute = false,

// after — resolve full path and fail with a diagnostic before launching
var gitPath = Environment.GetEnvironmentVariable("GIT_BINARY_PATH") ?? "git";
if (!File.Exists(gitPath) && Which(gitPath) is null)
{
    throw new InvalidOperationException("git not found on PATH; install git or set GIT_BINARY_PATH.");
}
FileName = gitPath,
UseShellExecute = false,
Defensive patterns

Strategy: validation

Validate before calling

// Run before invoking RunGit — fails fast with an actionable message
static void EnsureGitAvailable()
{
    var psi = new ProcessStartInfo("git", "--version")
    {
        UseShellExecute = false,
        CreateNoWindow = true,
        RedirectStandardOutput = true
    };
    try
    {
        using var p = Process.Start(psi);
        p?.WaitForExit(3000);
        if (p is null || p.ExitCode != 0)
            throw new InvalidOperationException("git not found on PATH. Install git or set GIT_BINARY_PATH.");
    }
    catch (Win32Exception)
    {
        throw new InvalidOperationException("git binary could not be launched (not installed / not executable).");
    }
}

Try / catch

try { EnsureGitAvailable(); RunGit(args); }
catch (Win32Exception ex) when (ex.NativeErrorCode == 2 /* ERROR_FILE_NOT_FOUND */)
{ /* git missing from PATH — install or fix PATH, do not retry blindly */ throw; }

Prevention

When it happens

Trigger: Process.StartInfo with FileName="git", UseShellExecute=false is invoked when git is not installed, not on the inherited PATH, not marked executable (Linux), or the process lacks launch permissions. Also fires in sandboxed/CI containers that omit git.

Common situations: Fresh dev machine or Docker image without git installed; CI runner that strips PATH; running the preprocessor under a service account whose profile doesn't source the login PATH; building inside a minimal container (alpine/musl) where git is a separate apk/apt package.

Related errors


AI-assisted analysis of unoplatform/uno@0418340488 (2026-08-13). Data as JSON: /api/errors/a3af692f406d03d0. Report an issue: GitHub.