{"record":{"id":"ed905d5cf677c68e","repo":"CoplayDev/unity-mcp","slug":"failed-to-parse-github-directory-tree-response","errorCode":null,"errorMessage":"Failed to parse GitHub directory tree response.","messagePattern":"Failed to parse GitHub directory tree response\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"MCPForUnity/Editor/Setup/SkillSyncService.cs","lineNumber":187,"sourceCode":"            {\n                return false;\n            }\n\n            repoInfo = new GitHubRepoInfo(owner, repo);\n            return true;\n        }\n\n        private static RemoteSnapshot FetchRemoteSnapshot(GitHubRepoInfo repoInfo, string branch, string subdir, Action<string> log)\n        {\n            using var client = CreateGitHubClient();\n            var commitSha = FetchBranchHeadCommitSha(client, repoInfo, branch, log);\n            var treeApiUrl = BuildTreeApiUrl(repoInfo, commitSha);\n            log?.Invoke($\"Fetching remote directory tree at commit {ShortCommit(commitSha)}...\");\n            var json = DownloadString(client, treeApiUrl);\n            var treeResponse = JsonUtility.FromJson<GitHubTreeResponse>(json);\n            if (treeResponse == null || treeResponse.tree == null)\n            {\n                throw new InvalidOperationException(\"Failed to parse GitHub directory tree response.\");\n            }\n\n            if (treeResponse.truncated)\n            {\n                throw new InvalidOperationException(\n                    \"GitHub returned a truncated directory tree (incomplete snapshot). \" +\n                    \"Sync was aborted to prevent accidental deletion of valid local files.\");\n            }\n\n            var normalizedSubdir = NormalizeRemotePath(subdir);\n            var subdirPrefix = string.IsNullOrEmpty(normalizedSubdir) ? string.Empty : $\"{normalizedSubdir}/\";\n            var remoteFiles = new Dictionary<string, string>(StringComparer.Ordinal);\n\n            foreach (var entry in treeResponse.tree)\n            {\n                if (!string.Equals(entry.type, \"blob\", StringComparison.Ordinal))\n                {\n                    continue;","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/CoplayDev/unity-mcp/blob/c21bf496bca87d54e75bad048563c3adb1782081/MCPForUnity/Editor/Setup/SkillSyncService.cs#L169-L205","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the sync log or capture the raw response body to see what was actually returned.","Disable or bypass any intercepting proxy / captive portal.","Retry; transient cache corruption at an intermediary often clears.","Verify the GitHub REST API directly with curl from the same machine."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    var snapshot = FetchRemoteSnapshot(repoInfo, branch, subdir, log);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"parse GitHub directory tree\"))\n{\n    log?.Invoke($\"Tree response was not valid GitHub JSON. Likely a proxy/captive page. Raw body should be inspected.\");\n    throw;\n}","preventionTips":["Run behind a direct connection or a transparent proxy, not an intercepting one.","Log raw response bodies during diagnosis.","Validate the response shape before trusting JsonUtility output."],"tags":["github","json","api","proxy"],"backgroundTag":null,"analyzedSha":"c21bf496bca87d54e75bad048563c3adb1782081","analyzedAt":"2026-08-13T17:36:56.095Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}