License Compliance widget link fails for MRs with deleted source project, causing 500

Summary

The License Compliance widget link is currently generated based on the source_project path to work correctly with both original and forked project MRs. However, when the source project no longer exists (e.g., the fork has been deleted but the pipeline exists on the target project), the MR cannot be opened.

Example MR: gitlab-org/frontend/fonts!20 (merged)

Steps to reproduce

  1. Enable MR pipelines in the target project.

    Example .gitlab-ci.yml
    stages:
      - test
    
    workflow:
      rules:
        - if: $CI_MERGE_REQUEST_IID
        - if: $CI_COMMIT_TAG
        - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
    
    test:
      stage: test
      script:
        - echo "Running a test"
  2. Create an MR from a forked project.

  3. Ensure the target project has a License Approval Policy enabled.

  4. Delete the forked project.

  5. Attempt to open the MR in the target project - you should see 500 error.

Example Project

Example MR showing the issue: gitlab-org/frontend/fonts!20 (merged)

What is the current bug behavior?

Opening an MR with a deleted forked project but existing pipeline results in a 500 error.

What is the expected correct behavior?

  • The MR page should open successfully even if the forked project has been deleted.
  • The License Compliance widget should still link to the correct pipeline.

Relevant logs and/or screenshots

Error Logs
ActionController::UrlGenerationError: No route matches {:action=>\"licenses\", :controller=>\"projects/pipelines\", :id=>#<Ci::Pipeline ref: \"refs/merge-requests/20/head\", sha: \"d2d17754ba6344f1f7e3f940a027c4714cbe4529\", before_sha: \"0000000000000000000000000000000000000000\", created_at: \"2025-04-23 20:38:37.408642000 +0000\", updated_at: \"2025-04-23 20:47:59.380219000 +0000\", tag: false, yaml_errors: nil, committed_at: nil, project_id: 41517813, status: \"failed\", started_at: \"2025-04-23 20:38:39.534085000 +0000\", finished_at: \"2025-04-23 20:47:59.366854000 +0000\", duration: 559, user_id: 181229, lock_version: 3, pipeline_schedule_id: nil, source: \"merge_request_event\", protected: false, config_source: \"repository_source\", failure_reason: nil, iid: 113, merge_request_id: 376746615, source_sha: nil, target_sha: nil, external_pull_request_id: nil, ci_ref_id: 157041496, locked: \"artifacts_locked\", partition_id: 102, id: 1782749928, auto_canceled_by_id: nil, auto_canceled_by_partition_id: nil, trigger_id: nil>, :namespace_id=>nil, :project_id=>nil}, possible unmatched constraints: [:namespace_id, :project_id]

"config/routes.rb:346:in `block (4 levels) in <main>'"
"ee/app/serializers/ee/merge_request_widget_entity.rb:52:in `block (3 levels) in <module:MergeRequestWidgetEntity>'"
"app/serializers/base_serializer.rb:16:in `represent'"
"app/serializers/merge_request_serializer.rb:10:in `represent'"
"app/helpers/issuables_helper.rb:58:in `serialize_issuable'"
"app/views/projects/merge_requests/_widget.html.haml:4"
"app/helpers/gitlab_script_tag_helper.rb:24:in `javascript_tag'"
"app/views/projects/merge_requests/_widget.html.haml:3"
"app/views/projects/merge_requests/_page.html.haml:69"
"app/views/projects/merge_requests/tabs/_pane.html.haml:7"
"app/views/projects/merge_requests/_page.html.haml:60"
"ee/app/helpers/ee/application_helper.rb:50:in `render_ce'"
"ee/app/views/projects/merge_requests/_page.html.haml:1"
"app/views/projects/merge_requests/show.html.haml:3"
"ee/app/helpers/ee/application_helper.rb:50:in `render_ce'"
"ee/app/views/projects/merge_requests/show.html.haml:2"
"app/controllers/application_controller.rb:153:in `render'"
"app/controllers/projects/merge_requests_controller.rb:494:in `render_html_page'"
"app/controllers/projects/merge_requests_controller.rb:425:in `block (2 levels) in show_merge_request'"
"app/controllers/projects/merge_requests_controller.rb:420:in `show_merge_request'"
"app/controllers/projects/merge_requests_controller.rb:102:in `show'"

Possible fixes

Update backend logic so that the License Compliance widget can still generate a valid link to the associated pipeline even when the source project has been deleted. For example, fall back to using the target project pipeline instead of relying on source_project.

Edited by Albina Yusupova