xai-org/grok-build · error

Failed to create tag: {stderr}

Error message

Failed to create tag: {stderr}

What it means

`grok plugin tag` executes `git tag [v<version>]` in the plugin directory and bails with 'Failed to create tag: {stderr}' when git exits non-zero, surfacing git's stderr. This reports local tag creation failures.

Source

Thrown at crates/codegen/xai-grok-pager/src/plugin_cmd.rs:761

        }
    }

    if dry_run {
        println!("Would create tag: {tag}");
        if push {
            println!("Would push tag to remote.");
        }
        return Ok(());
    }

    let mut cmd = std::process::Command::new("git");
    cmd.args(["tag", &tag]);
    if force {
        cmd.arg("--force");
    }
    let out = cmd.current_dir(&root).output()?;
    if !out.status.success() {
        bail!(
            "Failed to create tag: {}",
            String::from_utf8_lossy(&out.stderr)
        );
    }
    println!("Created tag: {tag}");

    if push {
        let mut push_cmd = std::process::Command::new("git");
        push_cmd.args(["push", "origin", &tag]);
        if force {
            push_cmd.arg("--force");
        }
        let out = push_cmd.current_dir(&root).output()?;
        if !out.status.success() {
            bail!(
                "Failed to push tag: {}",
                String::from_utf8_lossy(&out.stderr)
            );

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Delete or move the existing tag: `git tag -d v<version>`, or re-run with `--force`
  2. Initialize a repo if needed: `git init && git add -A && git commit`
  3. Run `git tag` manually in the directory to see the raw git error
  4. Ensure the directory is the intended git repository root

Example fix

// before
grok plugin tag .            # fatal: tag 'v1.0.0' already exists
// after
git tag -d v1.0.0
grok plugin tag .            # or: grok plugin tag . --force
Defensive patterns

Strategy: validation

Validate before calling

fn can_create_tag(root: &std::path::Path, tag: &str) -> Result<(), String> {
    if !root.join(".git").exists() {
        return Err(format!("{} is not a git repo", root.display()));
    }
    let exists = std::process::Command::new("git")
        .args(["rev-parse", "--verify", &format!("refs/tags/{tag}")])
        .current_dir(root)
        .output()
        .map(|o| o.status.success())
        .unwrap_or(false);
    if exists {
        return Err(format!("tag {tag} already exists; delete it or use --force"));
    }
    Ok(())
}

Type guard

fn tag_exists(root: &std::path::Path, tag: &str) -> bool {
    std::process::Command::new("git")
        .args(["rev-parse", "--verify", &format!("refs/tags/{tag}")])
        .current_dir(root)
        .output()
        .map(|o| o.status.success())
        .unwrap_or(false)
}

Try / catch

match cmd_tag(dir, false, false, false) {
    Err(e) if e.to_string().contains("Failed to create tag") => {
        eprintln!("Inspect git stderr: {e}; delete stale tag or init repo");
    }
    Ok(_) => {}
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Running `grok plugin tag` where `git tag` fails: the tag already exists without --force, the directory is not a git repo, or git is misconfigured.

Common situations: Tag v1.0.0 already exists from a previous release; directory lacks a .git folder; git version too old for flags used; detached/bare repo edge cases.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/42c2294e7686e6ca. Report an issue: GitHub.