Skip to content

NoMethodError in Ci::CommitStatusesFinder when tag has nil dereferenced_target

Summary

A NoMethodError is occurring in Ci::CommitStatusesFinder when attempting to call sha on a nil dereferenced_target for tags that point to missing commits.

Error Details

NoMethodError: undefined method `sha' for nil:NilClass (NoMethodError)

      ref_sha_pairs = refs.map { |ref| [ref.name, ref.dereferenced_target.sha] }
                                                                         ^^^^

Location: app/finders/ci/commit_statuses_finder.rb:36 in latest_pipeline_per_ref method

Backtrace

NoMethodError: undefined method `sha' for nil:NilClass (NoMethodError)

      ref_sha_pairs = refs.map { |ref| [ref.name, ref.dereferenced_target.sha] }
                                                                         ^^^^
  from app/finders/ci/commit_statuses_finder.rb:36:in `block in latest_pipeline_per_ref'
  from app/finders/ci/commit_statuses_finder.rb:36:in `map'
  from app/finders/ci/commit_statuses_finder.rb:36:in `latest_pipeline_per_ref'
  from app/finders/ci/commit_statuses_finder.rb:30:in `block in pipelines'
  from <internal:kernel>:124:in `then'
  from app/finders/ci/commit_statuses_finder.rb:26:in `pipelines'
  from app/finders/ci/commit_statuses_finder.rb:18:in `execute'
  from app/controllers/projects/tags_controller.rb:32:in `index'

Root Cause

The code assumes that all tags have a valid dereferenced_target, but some tags in repositories may point to commits that no longer exist (orphaned tags). When dereferenced_target is nil, calling .sha on it raises a NoMethodError.

This breaks the tags index page functionality.

Reproduction

This occurs in repositories that have tags pointing to missing commits (e.g., commits that were force-deleted or garbage collected).

Affected project: https://gitlab.com/freedesktop-sdk/mirrors/github/tpm2-software/tpm2-tools/-/tags

Suggested Fix

The code should handle cases where dereferenced_target is nil:

ref_sha_pairs = refs.filter_map { |ref| [ref.name, ref.dereferenced_target.sha] if ref.dereferenced_target }

Or add a nil check:

ref_sha_pairs = refs.map { |ref| [ref.name, ref.dereferenced_target&.sha] }.compact
Edited by Vasilii Iakliushin