pulumi/pulumi · error

getting HEAD commit info: %w

Error message

getting HEAD commit info: %w

What it means

Returned when repo.CommitObject(hash) fails to load the commit object that HEAD points to. The hash was resolved but the underlying commit object is missing or unreadable, so author/committer/message metadata cannot be set.

Source

Thrown at pkg/cmd/pulumi/metadata/metadata.go:467

}

func addGitCommitMetadata(repo *git.Repository, repoRoot string, m *backend.UpdateMetadata) error {
	// When running in a CI/CD environment, the current git repo may be running from a
	// detached HEAD and may not have have the latest commit message. We fall back to
	// CI-system specific environment variables when possible.
	ciVars := ciutil.DetectVars()

	// Commit at HEAD
	head, err := repo.Head()
	if err != nil {
		return fmt.Errorf("getting repository HEAD: %w", err)
	}

	hash := head.Hash()
	m.Environment[backend.GitHead] = hash.String()
	commit, commitErr := repo.CommitObject(hash)
	if commitErr != nil {
		return fmt.Errorf("getting HEAD commit info: %w", commitErr)
	}

	// If in detached head, will be "HEAD", and fallback to use value from CI/CD system if possible.
	// Otherwise, the value will be like "refs/heads/master".
	headName := head.Name().String()
	if headName == "HEAD" && ciVars.BranchName != "" {
		headName = ciVars.BranchName
	}
	if headName != "HEAD" {
		m.Environment[backend.GitHeadName] = headName
	}

	// If there is no message set manually, default to the Git commit's title.
	msg := strings.TrimSpace(commit.Message)
	if msg == "" && ciVars.CommitMessage != "" {
		msg = ciVars.CommitMessage
	}
	if m.Message == "" {

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Fetch full history: git fetch --unshallow (or increase fetch-depth in CI)
  2. Run git fsck to detect and diagnose corrupt/missing objects
  3. Verify git cat-file -t $(git rev-parse HEAD) returns 'commit'
  4. Re-clone the repository if the object store is damaged

Example fix

# before: GitHub Actions
- uses: actions/checkout@v4
  with:
    fetch-depth: 1
# after
- uses: actions/checkout@v4
  with:
    fetch-depth: 0
Defensive patterns

Strategy: try-catch

Validate before calling

if err := exec.Command("git", "cat-file", "-t", "HEAD").Run(); err != nil {
    return errors.New("HEAD object missing or corrupt; fetch full history")
}

Try / catch

if commitErr != nil {
    if errors.Is(commitErr, object.ErrObjectNotFound) {
        return fmt.Errorf("HEAD commit object not fetched (shallow clone?): %w", commitErr)
    }
    return fmt.Errorf("getting HEAD commit info: %w", commitErr)
}

Prevention

When it happens

Trigger: Shallow clones or CI checkouts where HEAD's commit object was not fetched (grafted/shallow history); corrupted or pruned git object store; HEAD resolving to a tag/annotated object that is not a commit.

Common situations: GitHub Actions/GitLab CI with fetch-depth: 1 combined with history rewriting; repos with gc-pruned objects; HEAD pointing at a tag object.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/8fc8d5e6ed041596. Report an issue: GitHub.