tailscale/tailscale · error

getting git hash: %w

Error message

getting git hash: %w

What it means

You are in a repo whose module path is not tailscale.com, so mkversion treats it as a repo that imports tailscale.com and records its commit hash (OtherHash) via `git rev-parse HEAD`. This error means that command failed in your repo - classically because HEAD is unborn (the repo was `git init`ed but has zero commits) or points at a missing/corrupt ref.

Source

Thrown at version/mkversion/mkversion.go:149

	if modPath == "" {
		return VersionInfo{}, fmt.Errorf("no module path in go.mod")
	}
	if modPath == "tailscale.com" {
		// Invoked in the tailscale.com repo directly, just no further info to
		// collect.
		v, err := infoFromDir(gitRoot)
		if err != nil {
			return VersionInfo{}, err
		}
		return mkOutput(v)
	}

	// We seem to be in a repo that imports tailscale.com. Find the
	// tailscale.com repo and collect additional info from it.
	otherHash, err := runner.output("git", "rev-parse", "HEAD")
	if err != nil {
		return VersionInfo{}, fmt.Errorf("getting git hash: %w", err)
	}
	otherDate, err := runner.output("git", "log", "-n1", "--format=%ct", "HEAD")
	if err != nil {
		return VersionInfo{}, fmt.Errorf("getting git date: %w", err)
	}

	// Note, this mechanism doesn't correctly support go.mod replacements,
	// or go workdirs. We only parse out the commit ref from go.mod's
	// "require" line, nothing else.
	tailscaleRef, err := tailscaleModuleRef(modBs)
	if err != nil {
		return VersionInfo{}, err
	}

	v, err := infoFromCache(tailscaleRef, runner)
	if err != nil {
		return VersionInfo{}, err
	}

View on GitHub (pinned to 6e0912f979)

Solutions

  1. Create at least one commit (`git commit --allow-empty -m init`) so HEAD resolves
  2. Reproduce manually with `git rev-parse HEAD` in the repo root to see git's exact complaint
  3. If the ref is broken, check `git fsck` and reset HEAD to a valid branch/commit

Example fix

# before
$ git rev-parse HEAD
fatal: ambiguous argument 'HEAD': unknown revision

# after
$ git add -A && git commit -m 'first commit'
$ git rev-parse HEAD
9ae23b5...
Defensive patterns

Strategy: validation

Validate before calling

// Require a resolvable HEAD before version collection.
if err := exec.Command("git", "-C", dir, "rev-parse", "--verify", "HEAD").Run(); err != nil {
	return fmt.Errorf("repo has no commits; commit before building: %w", err)
}
v, err := mkversion.InfoFrom(dir)

Type guard

func isGitHashError(err error) bool {
	return err != nil && strings.Contains(err.Error(), "getting git hash:")
}

Try / catch

v, err := mkversion.InfoFrom(dir)
if err != nil {
	if isGitHashError(err) {
		return fmt.Errorf("make an initial commit, then rebuild: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: InfoFrom run in a freshly initialized repo with no commits ('fatal: your current branch 'main' does not have any commits yet'), a detached HEAD pointing to a pruned ref, or a corrupted object database.

Common situations: CI pipelines that build an experimental repo before its first commit; local scratch repos that import tailscale.com; aggressively pruned/gc'd clones.

Related errors


AI-assisted analysis of tailscale/tailscale@6e0912f979 (2026-08-18). Data as JSON: /api/errors/4e77700e6f1ebe0f. Report an issue: GitHub.