{"record":{"id":"09e81f7ae6c489cd","repo":"github/github-mcp-server","slug":"failed-to-read-file-content-w","errorCode":null,"errorMessage":"failed to read file content: %w","messagePattern":"failed to read file content: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/repository_resource.go","lineNumber":213,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"failed to get raw content: %w\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\t_ = resp.Body.Close()\n\t\t}()\n\t\t// If the raw content is not found, we will fall back to the GitHub API (in case it is a directory)\n\t\tswitch {\n\t\tcase resp.StatusCode == http.StatusOK:\n\t\t\text := filepath.Ext(path)\n\t\t\tmimeType := resp.Header.Get(\"Content-Type\")\n\t\t\tif ext == \".md\" {\n\t\t\t\tmimeType = \"text/markdown\"\n\t\t\t} else if mimeType == \"\" {\n\t\t\t\tmimeType = mime.TypeByExtension(ext)\n\t\t\t}\n\n\t\t\tcontent, err := io.ReadAll(resp.Body)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to read file content: %w\", err)\n\t\t\t}\n\n\t\t\tswitch {\n\t\t\tcase strings.HasPrefix(mimeType, \"text\"), strings.HasPrefix(mimeType, \"application\"):\n\t\t\t\treturn &mcp.ReadResourceResult{\n\t\t\t\t\tContents: []*mcp.ResourceContents{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tURI:      request.Params.URI,\n\t\t\t\t\t\t\tMIMEType: mimeType,\n\t\t\t\t\t\t\tText:     string(content),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t}, nil\n\t\t\tdefault:\n\t\t\t\tvar buf bytes.Buffer\n\t\t\t\tbase64Encoder := base64.NewEncoder(base64.StdEncoding, &buf)\n\t\t\t\t_, err := base64Encoder.Write(content)\n\t\t\t\tif err != nil {","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/repository_resource.go#L195-L231","documentation":"Thrown by the repo:// resource read handler (pkg/github/repository_resource.go) after GitHub's raw content endpoint already returned HTTP 200: io.ReadAll failed while streaming the body. The wrapped error is almost always a transport failure (connection reset, unexpected EOF, deadline exceeded) that hit mid-download, after status and headers were received. The file exists and is reachable; only the body transfer did not complete.","triggerScenarios":"Reading a repo://raw/... resource URI when the connection drops between headers and the last body byte: rawClient.GetRawContent returned 200, then a proxy or raw.githubusercontent.com reset the stream, the client context deadline expired during a large file, or the TLS connection broke mid-transfer.","commonSituations":"Reading very large files (hundreds of MB) through read_resource; aggressive HTTP client timeouts on the raw client; corporate proxies that cut long transfers; flaky CI or mobile networks.","solutions":["Retry the read_resource call once - mid-body interruptions are usually transient and succeed on a second attempt","Check the file size first (e.g. via get_file_contents metadata) and avoid streaming files above your reliability limit","Raise the raw client's HTTP timeout or pass a context with a longer deadline when reading large files","If it reproduces only on one network, inspect proxy/firewall treatment of raw.githubusercontent.com"],"exampleFix":"// before\ncontent, err := io.ReadAll(resp.Body)\nif err != nil {\n    return nil, fmt.Errorf(\"failed to read file content: %w\", err)\n}\n// after - bound the read and signal transiency to callers\nconst maxRawBytes = 64 << 20\ncontent, err := io.ReadAll(io.LimitReader(resp.Body, maxRawBytes))\nif err != nil {\n    return nil, fmt.Errorf(\"failed to read file content (transfer interrupted, likely transient): %w\", err)\n}","handlingStrategy":"retry","validationCode":"// Before read_resource on a repo:// URI, confirm the blob is small enough to stream reliably\nmeta, _, err := client.Repositories.GetContents(ctx, owner, repo, path, nil)\nif err == nil && meta != nil && meta.GetSize() > 50<<20 {\n    return fmt.Errorf(\"file %s is %d bytes; fetch it with git instead of read_resource\", path, meta.GetSize())\n}","typeGuard":"func isTransientBodyErr(err error) bool {\n\tvar netErr net.Error\n\tif errors.As(err, &netErr) {\n\t\treturn true\n\t}\n\treturn errors.Is(err, io.ErrUnexpectedEOF) ||\n\t\terrors.Is(err, syscall.ECONNRESET) ||\n\t\tstrings.Contains(err.Error(), \"http2: stream closed\")\n}","tryCatchPattern":"var result *mcp.ReadResourceResult\nerr := retry(ctx, 3, 500*time.Millisecond, func() error {\n    var e error\n    result, e = readResource(ctx, repoURI)\n    if e != nil && isTransientBodyErr(e) {\n        return e // retryable\n    }\n    return nil\n})\nif err != nil {\n    return fmt.Errorf(\"raw file read failed after retries: %w\", err)\n}","preventionTips":["Avoid read_resource on large binaries; use git clone or the contents API with a raw media type instead","Set generous timeouts on raw file reads proportional to file size","Retry once on unexpected EOF or connection reset before escalating to the user"],"tags":["go","mcp","github-api","network","io","resource"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}