zed-industries/zed · error

failed to add remote {url} for git repository {git_dir:?}

Error message

failed to add remote {url} for git repository {git_dir:?}

What it means

Raised in `checkout_repo` (crates/extension/src/extension_builder.rs:369) after a fresh `git init`, when `git --git-dir <dir>/.git remote add origin <url>` exits non-zero, so the builder cannot register the grammar repository's URL as the `origin` remote. Since the directory was just initialized, this failure is almost always an environment problem rather than a state conflict, and the subsequent shallow `git fetch` of the pinned revision cannot succeed without the remote.

Source

Thrown at crates/extension/src/extension_builder.rs:369

                .with_context(|| format!("creating grammar directory {directory:?}"))?;
            let init_output = util::command::new_command("git")
                .arg("init")
                .current_dir(directory)
                .output()
                .await?;
            anyhow::ensure!(
                init_output.status.success(),
                "failed to run `git init` in directory {directory:?}"
            );

            let remote_add_output = util::command::new_command("git")
                .arg("--git-dir")
                .arg(&git_dir)
                .args(["remote", "add", "origin", url])
                .output()
                .await
                .context("executing `git remote add`")?;
            anyhow::ensure!(
                remote_add_output.status.success(),
                "failed to add remote {url} for git repository {git_dir:?}"
            );
        }

        let fetch_output = util::command::new_command("git")
            .arg("--git-dir")
            .arg(&git_dir)
            .args(["fetch", "--depth", "1", "origin", rev])
            .output()
            .await
            .context("executing `git fetch`")?;

        let checkout_output = util::command::new_command("git")
            .arg("--git-dir")
            .arg(&git_dir)
            .args(["checkout", rev])
            .current_dir(directory)

View on GitHub (pinned to 9d272b0363)

Solutions

  1. Inspect .git/config in the grammar directory and remove any `url.*.insteadOf` global rewrites (`git config --global --unset url.ssh://... .insteadOf`) or unset GIT_CONFIG_GLOBAL conflicts, then retry the build.
  2. Delete the grammar directory (`rm -rf <directory>`) so the builder re-runs `git init` and `remote add` from scratch.
  3. Check that the parent filesystem is writable and not full (`df -h`, `mount | grep <path>`).
  4. Unset interfering environment variables (GIT_DIR, GIT_WORK_TREE, GIT_CONFIG_GLOBAL) in the shell before building; the builder sets GIT_CONFIG_GLOBAL=/dev/null for some calls but not all.

Example fix

// before (shell): global insteadOf rewrite breaks remote add
$ git config --global url."ssh://git@corp/".insteadOf "https://github.com/"
$ zed: error: failed to add remote https://github.com/tree-sitter/tree-sitter-yaml ...

// after (shell): scope the rewrite only to work repos, or unset it
$ git config --global --unset-all url."ssh://git@corp/".insteadOf
$ rm -rf ~/.local/share/zed/extensions/work/tree-sitter-yaml
Defensive patterns

Strategy: validation

Validate before calling

// Remove git config rewrites and env interference before building
const { execSync } = require('child_process');
function precheck(url) {
  delete process.env.GIT_DIR;
  delete process.env.GIT_WORK_TREE;
  try {
    execSync(`git config --global --get-regexp 'url\..*\.insteadof'`, { stdio: 'pipe' });
    console.warn('global url.insteadOf rewrites present; they may corrupt remote add');
  } catch { /* none found */ }
}

Try / catch

try {
  await buildExtension(path);
} catch (err) {
  if (String(err).includes("failed to add remote")) {
    console.error("Check .git/config, url.insteadOf rewrites, and disk writability:", err.message);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling `compile_grammar` -> `checkout_repo` for a grammar whose directory doesn't exist yet, where `git remote add origin <url>` fails: `git` not on PATH (process spawn failure is a distinct context error, but a non-zero status can occur if the directory is not actually a git repo, e.g. `git init` above silently skipped due to a wrapped/incompatible git binary), the .git dir is missing or corrupted between the two calls, an invalid remote name/URL rejected by git configuration (e.g. hooks/insteadOf rewriting the URL to empty), or file-system errors writing .git/config (read-only or full disk).

Common situations: Corporate git config with `url.<x>.insteadOf` or `insteadOf` rewrites corrupting the remote URL; antivirus or filesystem sync (Dropbox/OneDrive) locking .git/config on Windows; a full or read-only disk; custom GIT_DIR/GIT_CONFIG environment variables interfering with the spawned git process.

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


AI-assisted analysis of zed-industries/zed@9d272b0363 (2026-09-12). Data as JSON: /api/errors/938d76bb9628cf20. Report an issue: GitHub.