Repositories API merge_base reports the last ref instead of the missing ref

Summary

GET /projects/:id/repository/merge_base can return a misleading Could not find ref error. When one ref is missing and a later ref exists, the response names the last ref rather than the actual missing ref. Reversing the same two refs changes the error message.

Observed on self-managed GitLab 18.8.9-ee.

API documentation: https://docs.gitlab.com/api/repositories/#get-merge-base

Steps to reproduce

Use a project with an existing default branch named main.

  1. Request:
curl --header "PRIVATE-TOKEN: <token>" \
  --url "https://gitlab.example.com/api/v4/projects/<project-id>/repository/merge_base?refs[]=definitely-missing-ref&refs[]=main"
  1. Observe:
{"message":"Could not find ref: main"}
  1. Reverse the refs:
curl --header "PRIVATE-TOKEN: <token>" \
  --url "https://gitlab.example.com/api/v4/projects/<project-id>/repository/merge_base?refs[]=main&refs[]=definitely-missing-ref"
  1. Observe:
{"message":"Could not find ref: definitely-missing-ref"}

A request with two valid refs succeeds, confirming that main exists.

Current behavior

When merge-base calculation fails because a ref cannot be resolved, the error appears to report the last entry in refs[], even if that ref exists. The reported missing ref therefore depends on parameter order.

Expected behavior

The response identifies the ref that cannot be resolved, independent of argument order. For the first request:

{"message":"Could not find ref: definitely-missing-ref"}

Impact

API clients may misdiagnose an existing default branch as missing and investigate or modify the wrong ref. This is particularly confusing when ephemeral tags or commits expire.

Workaround

Put the ref most likely to be missing last, or pre-resolve refs before calling the endpoint.

Possible fix

Resolve or validate each supplied ref and return the actual unresolved value, or propagate the invalid ref from the Gitaly merge-base failure rather than deriving it from the request's final element.

Edited by 🤖 GitLab Bot 🤖