CoplayDev/unity-mcp · error · InvalidOperationException

Failed to parse GitHub directory tree response.

Error message

Failed to parse GitHub directory tree response.

What it means

After the Git Trees API call returns 2xx, JsonUtility.FromJson<GitHubTreeResponse> yields null or a response whose tree array is null. This means the body was not the expected GitHub tree JSON even though the HTTP status was success.

Source

Thrown at MCPForUnity/Editor/Setup/SkillSyncService.cs:187

            {
                return false;
            }

            repoInfo = new GitHubRepoInfo(owner, repo);
            return true;
        }

        private static RemoteSnapshot FetchRemoteSnapshot(GitHubRepoInfo repoInfo, string branch, string subdir, Action<string> log)
        {
            using var client = CreateGitHubClient();
            var commitSha = FetchBranchHeadCommitSha(client, repoInfo, branch, log);
            var treeApiUrl = BuildTreeApiUrl(repoInfo, commitSha);
            log?.Invoke($"Fetching remote directory tree at commit {ShortCommit(commitSha)}...");
            var json = DownloadString(client, treeApiUrl);
            var treeResponse = JsonUtility.FromJson<GitHubTreeResponse>(json);
            if (treeResponse == null || treeResponse.tree == null)
            {
                throw new InvalidOperationException("Failed to parse GitHub directory tree response.");
            }

            if (treeResponse.truncated)
            {
                throw new InvalidOperationException(
                    "GitHub returned a truncated directory tree (incomplete snapshot). " +
                    "Sync was aborted to prevent accidental deletion of valid local files.");
            }

            var normalizedSubdir = NormalizeRemotePath(subdir);
            var subdirPrefix = string.IsNullOrEmpty(normalizedSubdir) ? string.Empty : $"{normalizedSubdir}/";
            var remoteFiles = new Dictionary<string, string>(StringComparer.Ordinal);

            foreach (var entry in treeResponse.tree)
            {
                if (!string.Equals(entry.type, "blob", StringComparison.Ordinal))
                {
                    continue;

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Inspect the sync log or capture the raw response body to see what was actually returned.
  2. Disable or bypass any intercepting proxy / captive portal.
  3. Retry; transient cache corruption at an intermediary often clears.
  4. Verify the GitHub REST API directly with curl from the same machine.
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    var snapshot = FetchRemoteSnapshot(repoInfo, branch, subdir, log);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("parse GitHub directory tree"))
{
    log?.Invoke($"Tree response was not valid GitHub JSON. Likely a proxy/captive page. Raw body should be inspected.");
    throw;
}

Prevention

When it happens

Trigger: A transparent proxy or captive portal returns 200 with an HTML login/captive page; the GitHub API response schema changed; the body was truncated mid-stream producing partial JSON that JsonUtility silently nulls out.

Common situations: Corporate proxy intercepts the request and returns a 200 status block page; CI runs behind a MITM that rewrites responses; an upstream CDN cache served a stale/wrong payload.

Understand the failure class

Related errors


AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13). Data as JSON: /api/errors/ed905d5cf677c68e. Report an issue: GitHub.