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.
- 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"- Observe:
{"message":"Could not find ref: main"}- 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"- 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.