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
- Delete or move the existing tag: `git tag -d v<version>`, or re-run with `--force`
- Initialize a repo if needed: `git init && git add -A && git commit`
- Run `git tag` manually in the directory to see the raw git error
- 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
- Check for an existing tag before releasing
- Ensure the plugin dir is inside a git repo with a commit
- Bump the version in plugin.json each release so tags don't collide
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
- Working tree is dirty. Commit changes first, or use --force.
- {e}
- Failed to load manifest: {e}
- No plugin.json found in {path}.
- no target specified
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/42c2294e7686e6ca.
Report an issue: GitHub.