{"record":{"id":"dc1c024061c4aafa","repo":"github/github-mcp-server","slug":"failed-to-get-file-tree","errorCode":null,"errorMessage":"failed to get file tree","messagePattern":"failed to get file tree","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/github/repository_resource_completions.go","lineNumber":265,"sourceCode":"\tif refVal == \"\" {\n\t\trefVal = \"HEAD\"\n\t}\n\n\t// Determine the prefix to complete (directory path or file path)\n\tprefix := argValue\n\tif prefix != \"\" && !strings.HasSuffix(prefix, \"/\") {\n\t\tlastSlash := strings.LastIndex(prefix, \"/\")\n\t\tif lastSlash >= 0 {\n\t\t\tprefix = prefix[:lastSlash+1]\n\t\t} else {\n\t\t\tprefix = \"\"\n\t\t}\n\t}\n\n\t// Get the tree for the ref (recursive)\n\ttree, _, err := client.Git.GetTree(ctx, owner, repo, refVal, true)\n\tif err != nil || tree == nil {\n\t\treturn nil, errors.New(\"failed to get file tree\")\n\t}\n\n\t// Collect immediate children of the prefix (files and directories, no duplicates)\n\tdirs := map[string]struct{}{}\n\tfiles := map[string]struct{}{}\n\tprefixLen := len(prefix)\n\tfor _, entry := range tree.Entries {\n\t\tif !strings.HasPrefix(entry.GetPath(), prefix) {\n\t\t\tcontinue\n\t\t}\n\t\trel := entry.GetPath()[prefixLen:]\n\t\tif rel == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\t// Only immediate children\n\t\tslashIdx := strings.Index(rel, \"/\")\n\t\tif slashIdx >= 0 {\n\t\t\t// Directory: only add the directory name (with trailing slash), prefixed with full path","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/repository_resource_completions.go#L247-L283","documentation":"Thrown by completePath when client.Git.GetTree(ctx, owner, repo, refVal, true) fails or returns nil. The call fetches the full repository tree recursively; the underlying error is discarded and replaced. The most common real cause is GitHub rejecting a recursive fetch of a very large tree (409 Conflict / 'tree is too large' style errors), but invalid refs and auth failures also land here.","triggerScenarios":"Path completion against a repository whose tree exceeds GitHub's recursive-fetch limits (very large monorepos); refVal resolves to a nonexistent branch/SHA/tag; token lacks read access to the repo; transient network/API failure; tree response nil.","commonSituations":"Autocompleting paths on huge repositories (e.g. linux-scale monorepos); ref segment resolved to a value that was deleted or typo'd; fine-grained PAT without 'Contents: read' on the target repo.","solutions":["Verify the ref exists (git ls-remote or GET /repos/{owner}/{repo}/git/ref/{ref}) before completing paths","For very large repos, avoid recursive tree completion: fetch the root tree non-recursively and walk only the prefix directory","Check token scopes/permissions on the target repository","Wrap the underlying error with %w so the true HTTP status is visible instead of the generic message","Retry once on transient 5xx/network failures"],"exampleFix":"// before\ntree, _, err := client.Git.GetTree(ctx, owner, repo, refVal, true)\nif err != nil || tree == nil {\n    return nil, errors.New(\"failed to get file tree\")\n}\n\n// after\ntree, resp, err := client.Git.GetTree(ctx, owner, repo, refVal, true)\nif err != nil {\n    return nil, fmt.Errorf(\"failed to get file tree (ref %s, HTTP %d): %w\", refVal, resp.StatusCode, err)\n}\nif tree == nil {\n    return nil, errors.New(\"failed to get file tree: nil response\")\n}","handlingStrategy":"validation","validationCode":"// Validate the ref exists before requesting the recursive tree\n_, resp, err := client.Git.GetRef(ctx, owner, repo, \"refs/heads/\"+refVal)\nif err != nil || resp == nil {\n    // ref invalid; skip path completion\n    return nil\n}","typeGuard":null,"tryCatchPattern":"// Degrade path completion on tree-fetch failure instead of failing the request\nvalues, err := completePath(ctx, client, resolved, argValue)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to get file tree\") {\n        return &mcp.CompleteResult{Completion: mcp.CompletionResultDetails{Values: []string{}}}, nil\n    }\n    return nil, err\n}","preventionTips":["For very large repositories, avoid recursive tree completions; walk directories non-recursively per prefix","Always complete a concrete ref (branch/sha/tag) rather than defaulting to HEAD so failures are reproducible","Grant the token Contents:read on target repos","Wrap underlying GetTree errors with %w when embedding to expose HTTP status (409 too-large, 404 bad ref, 401 auth)"],"tags":["completions","mcp","git-tree","large-repos","github-api"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}