Azure DevOps の「TF401175: The version descriptor <Branch: … > could not be resolved to a version in the repository …」
「<Branch: と > の間の名前とちょうど同じブランチ(またはタグ)が、このリポジトリに無い」という意味です。サーバーは受け取った名前をそのまま出し、空白を1つ置いて > で閉じます。1文字ずつ読んでください。前に付いた refs/heads/、大文字と小文字の違い、末尾の空白、# のつもりの %23 は、どれもここに見えます。文の終わりには、探したリポジトリの名前が出ます。
答えの全体
2026年10月30日に dev.azure.com の公開リポジトリへ、サインインなしで、無いブランチからファイルを読んで確かめました:
GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repository}/items
?path=/README.md&versionDescriptor.version=no-such-branch&versionDescriptor.versionType=branch&api-version=7.1
HTTP/1.1 404 Not Found
{"$id": "1", "innerException": null,
"message": "TF401175:The version descriptor <Branch: no-such-branch > could not be resolved to a version in the repository dotnet-public-wiki",
"typeName": "Microsoft.TeamFoundation.Git.Server.GitUnresolvableToCommitException, Microsoft.TeamFoundation.Git.Server",
"typeKey": "GitUnresolvableToCommitException", "errorCode": 0, "eventId": 3000}
同じ試験で TF401175 になったもの
main:200 でファイルが返りました。下のほかの名前は、どれも 404 と TF401175 でした。refs/heads/main(refs%2Fheads%2Fmainと符号にしても同じ):<Branch: refs/heads/main >。versionType=branchのとき、名前にrefs/heads/は付けません。MAIN:大文字と小文字も合っている必要があります。- 末尾に空白の付いた
main(main%20):>の前の空白が2つになります。 refs/pull/1/mergeとpull/1/merge:プルリクエストのマージの参照はブランチではありません。versionType=tagのmain:<Tag: main >。種類も探す条件のうちです。diffs/commits(baseVersionかtargetVersionが無い名前)、commits?branch=、commits?searchCriteria.itemVersion.version=も同じ 404 でした。Web ポータルでも、?version=GBno-such-branchのリンク(GBはブランチ、GTはタグ、GCはコミット)で、画面に同じ TF401175 が出ました。
TF401175 にならない2つ:
- 空の版はエラーになりません。
versionDescriptor.version=は既定のブランチからファイルを 200 で返し、baseVersionが空のdiffs/commitsはmainをmainと比べました(変更なし・aheadCount0)。パイプラインの変数が空だと、エラーなしで違う答えが返ることがあります。 - コミットは別のエラーです。
versionType=commitで、リポジトリに無い40文字の ID はTF401029: Couldn't find Git commit with ID …(404)、7文字の ID は 400 のAn object ID must be 40 characters long and only have hex digits.でした。
公開の報告に出てくる原因
- プルリクエストの完了のときに消されたソースブランチ。プルリクエストは
sourceRefNameにその名前を持ち続けるので、後から名前で読むものは TF401175 になります:マージの後片付けをする依存関係の更新サービス(2024年)、プルリクエストにコメントするスキャナー(2024年)、プルリクエストの一覧がdiffs/commits?baseVersion=<ソースブランチ>で失敗した IDE のプラグイン(2024年・次の版で直った)。プルリクエストのファイルはコミットで読みます。ID はプルリクエストのlastMergeSourceCommitとlastMergeTargetCommitに残っています。 - パイプラインのブランチの変数をそのまま渡した。
Build.SourceBranchはrefs/heads/main、プルリクエストのビルドではrefs/pull/1/mergeで、どちらもブランチの名前ではありません。Build.SourceBranchNameでは直りません。最後の部分だけなので、refs/heads/feature/toolsはtoolsになります(Microsoft の定義済みの変数)。前を切ります:b="${BUILD_SOURCEBRANCH#refs/heads/}"プルリクエストのビルドで、レビュー中のブランチはSystem.PullRequest.SourceBranchです(ブランチのポリシーがビルドを走らせたときだけ入ります)。2021年には、プルリクエストを作るパイプラインのタスクがrefs/pull/12/mergeをbaseVersion=2/mergeにしていました。今は先にrefs/heads/とrefs/pull/を外しています。 - 別のリポジトリ。2021年、同じタスクを2つ目のリポジトリにプルリクエストを開く設定にすると、パイプラインがビルドしたブランチをそのリポジトリに尋ねていました。そのブランチは1つ目のリポジトリにしかありません。メッセージの終わりのリポジトリが、尋ねた先です。
- リンクが名前を変えた。2019年、エディターの「リモートで開く」のリンクが
#123.fix-all-the-thingsというブランチを%2523123…にしていました。2回符号にしたので、サーバーは%23で始まる名前を探しました。#の入った名前は、ちょうど1回だけ符号にします。 - 既定のブランチが
mainでない。2022年、移行のツールが、mainの無いリポジトリにmainを尋ねていました。GET …/repositories/{repository}のdefaultBranchに、どのブランチかが出ます。
確かめること
- 名前は生の応答から写して、ブランチと比べます。
GET …/refs?filter=heads/<名前の始まり>は、名前がそれで始まるブランチをrefs/heads/…の形で並べます。 - リポジトリは合っていますか。探した先はメッセージに出ています。
- ブランチは消されていませんか。Web ポータルの Branches で名前をそのまま検索し、Search for exact match in deleted branches を選ぶと、誰がいつ消したかが出て、Restore branch で戻せます。消したブランチは期限なしで残っています(Microsoft の削除された Git ブランチを復元する)。
- 名前が合っていれば、種類を見ます。ブランチをタグとして尋ねると見つかりません。逆も同じです。
IntelliJ IDEA と Rider で Azure DevOps のプルリクエストを
Azure DevOps Pull Requests は、Lesstep が作っている JetBrains IDE(2024.1 以降)と Android Studio のプラグインです。組織・プロジェクト・リポジトリを git のリモートから読み、自分のレビューを待っているプルリクエストを IDE のツールウィンドウに並べます。Azure DevOps Services でも Azure DevOps Server でも使えます。プルリクエストのファイルは、プルリクエストの最後のマージのソースとターゲットのコミット ID で読むので、ソースブランチが消されても差分は止まりません。ブランチの名前を使うのはプルリクエストを作るときだけで、サーバーに無いのがソースかターゲットかを名指しで示します。レビューの受け箱と差分は無料、投票・コメント・完了・作成は Pro(30日間の無料試用つき)です。画面は日本語です。
Azure DevOps は Microsoft Corporation の商標、IntelliJ IDEA と Rider は JetBrains s.r.o. の商標です。このページは Microsoft・JetBrains のいずれとも提携しておらず、承認も受けていません。
ほかに:TF401174:その版にファイルが無い · TF401398:ソースかターゲットのブランチが無い · TF401019:リポジトリが無いか、許可が無い · English