CoplayDev/unity-mcp · error · InvalidOperationException
Failed to resolve branch head commit SHA for: {branch}
Error message
Failed to resolve branch head commit SHA for: {branch} What it means
FetchBranchHeadCommitSha parses the Branches API response and expects branchResponse.commit.sha. If that field is null/empty/whitespace after parsing a 2xx response, the SHA cannot be resolved and the sync cannot proceed.
Source
Thrown at MCPForUnity/Editor/Setup/SkillSyncService.cs:255
if (remoteFiles.Count == 0)
{
throw new InvalidOperationException($"Remote directory not found: {normalizedSubdir}");
}
log?.Invoke($"Remote file count: {remoteFiles.Count}");
return new RemoteSnapshot(commitSha, normalizedSubdir, remoteFiles);
}
private static string FetchBranchHeadCommitSha(HttpClient client, GitHubRepoInfo repoInfo, string branch, Action<string> log)
{
var branchApiUrl = BuildBranchApiUrl(repoInfo, branch);
log?.Invoke($"Fetching branch head commit...");
var branchJson = DownloadString(client, branchApiUrl);
var branchResponse = JsonUtility.FromJson<GitHubBranchResponse>(branchJson);
var commitSha = branchResponse?.commit?.sha?.Trim();
if (string.IsNullOrWhiteSpace(commitSha))
{
throw new InvalidOperationException($"Failed to resolve branch head commit SHA for: {branch}");
}
return commitSha;
}
private static string BuildBranchApiUrl(GitHubRepoInfo repoInfo, string branch)
{
return $"https://api.github.com/repos/{Uri.EscapeDataString(repoInfo.Owner)}/{Uri.EscapeDataString(repoInfo.Repo)}/branches/{Uri.EscapeDataString(branch)}";
}
private static string BuildTreeApiUrl(GitHubRepoInfo repoInfo, string reference)
{
return $"https://api.github.com/repos/{Uri.EscapeDataString(repoInfo.Owner)}/{Uri.EscapeDataString(repoInfo.Repo)}/git/trees/{Uri.EscapeDataString(reference)}?recursive=1";
}
private static string BuildRawFileUrl(GitHubRepoInfo repoInfo, string commitSha, string remoteFilePath)
{
var encodedPath = string.Join("/",View on GitHub (pinned to c21bf496bc)
Solutions
- Verify the branch name is correct (case-sensitive on some repos).
- Capture and inspect the raw Branches API response body.
- Retry in case of a transient intermediary issue.
- Confirm there is no proxy rewriting the JSON payload.
Defensive patterns
Strategy: try-catch
Try / catch
try
{
var sha = FetchBranchHeadCommitSha(client, repoInfo, branch, log);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("branch head commit SHA"))
{
log?.Invoke($"Could not resolve SHA for branch '{branch}'. Verify the branch exists and the API response is intact.");
throw;
} Prevention
- Use the correct branch name (case-sensitive where relevant).
- Inspect raw API responses when SHA resolution fails unexpectedly.
- Prefer the default branch unless you need a specific one.
When it happens
Trigger: The branch API returned 2xx but with a schema that did not deserialize commit.sha (API change, proxy-rewritten body); the response parsed into a default object because JsonUtility could not map the fields.
Common situations: GitHub API schema drift; an intermediary returned a 200 with a different JSON shape; extremely rare compared to the 404 path which surfaces as error 67.
Related errors
- Failed to parse GitHub directory tree response.
- GitHub returned a truncated directory tree (incomplete snaps
- Remote directory not found: {normalizedSubdir}
- GitHub request failed: {(int)response.StatusCode} {response.
- fal submit returned no request_id: {truncated_response}
AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13).
Data as JSON: /api/errors/9e07e8d79f5331e0.
Report an issue: GitHub.