vectordotdev/vector · error

wrote but `git add` failed — stage it manually before…

Error message

wrote {} but `git add` failed — stage it manually before running `vdev check changelog-fragments`.

What it means

After writing the fragment file, `vdev changelog new` runs `git add` on it so the fragments checker (which scans added files) sees it. If `git add` exits non-zero, the command bails with this error telling the developer the file was written but not staged.

Solutions

  1. Read the stderr printed by the with_context wrapper ('failed to run `git add ...`') and the git error itself, fix that cause (e.g. remove stale .git/index.lock)
  2. Run `git add changelog.d/<your-fragment>.md` manually as the message suggests
  3. Verify `git status` works and you are in the Vector repo root (dubious-ownership: `git config --global --add safe.directory <path>`), then re-run

Example fix

# before
rm -f .git/index.lock
git add changelog.d/my_fix.md
# after: re-run
vdev changelog new bug_fix my_fix
Defensive patterns

Strategy: try-catch

Validate before calling

const st = spawnSync("git", ["status"]); if (st.status !== 0 || /not a git repository|dubious ownership/.test(st.stderr.toString())) fixGitEnv();

Try / catch

try { vdevChangelogNew(type, slug); } catch (e) { if (/git add/.test(e.message)) { execSync(`git add changelog.d/*.md`); console.warn("staged manually"); } else throw e; }

Prevention

When it happens

Trigger: `git add -- <file>` returns a non-zero exit status after the fragment file was successfully written — e.g. git refuses due to index lock, .gitignore/.git exclude rules with refuse semantics, hooks, or git binary/environment problems.

Common situations: A stale .git/index.lock left by a crashed git process; running the command in a worktree with unusual git config; a pre-commit/applypatch hook failing; repo ownership mismatch ('dubious ownership').

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 vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/baab61950333e682. Report an issue: GitHub.

Appendix: source

Thrown at vdev/src/commands/changelog/new.rs:62

        let Some(entry) = FRAGMENT_TYPES
            .iter()
            .find(|t| t.name == self.fragment_type.as_str())
        else {
            bail!("unknown fragment type '{}'", self.fragment_type);
        };
        let content = render_template(entry, &author);
        fs::write(&file, content)?;

        // `git add` the new fragment so the checker (which scans `git diff --diff-filter=A`)
        // picks it up immediately without a manual staging step. Report the failure if it
        // happens — the file is on disk, but the checker won't see it until it's staged.
        let status = Command::new("git")
            .args(["add", "--"])
            .arg(&file)
            .status()
            .with_context(|| format!("failed to run `git add {}`", file.display()))?;
        if !status.success() {
            bail!(
                "wrote {} but `git add` failed — stage it manually before running `vdev check changelog-fragments`.",
                file.display()
            );
        }

        info!("Created {}", relative(&repo_root, &file).display());
        info!("Edit the file, then run `vdev check changelog-fragments` to validate.");
        Ok(())
    }
}

/// A slug must be one filename component: ASCII alnum, `_`, or `-` only.
/// Rejects path separators, `..`, absolute paths, and anything with punctuation.
fn validate_slug(slug: &str) -> Result<()> {
    if slug.is_empty() {
        bail!("slug must not be empty");
    }
    if !slug

View on GitHub (pinned to bdb87aeaa4)