{"record":{"id":"225e3cbf0c3e814f","repo":"github/github-mcp-server","slug":"failed-to-get-raw-url-w-225e3c","errorCode":null,"errorMessage":"failed to get Raw URL: %w","messagePattern":"failed to get Raw URL: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/dependencies.go","lineNumber":377,"sourceCode":"\tgraphqlURL, err := d.apiHosts.GraphqlURL(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get GraphQL URL: %w\", err)\n\t}\n\n\tgqlClient := githubv4.NewEnterpriseClient(graphqlURL.String(), gqlHTTPClient)\n\treturn gqlClient, nil\n}\n\n// GetRawClient implements ToolDependencies.\nfunc (d *RequestDeps) GetRawClient(ctx context.Context) (*raw.Client, error) {\n\tclient, err := d.GetClient(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trawURL, err := d.apiHosts.RawURL(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get Raw URL: %w\", err)\n\t}\n\n\trawClient, err := raw.NewClient(client, rawURL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create raw client: %w\", err)\n\t}\n\n\treturn rawClient, nil\n}\n\n// GetRepoAccessCache implements ToolDependencies.\nfunc (d *RequestDeps) GetRepoAccessCache(ctx context.Context) (*lockdown.RepoAccessCache, error) {\n\tif !d.lockdownMode {\n\t\treturn nil, nil\n\t}\n\n\tgqlClient, err := d.GetGQLClient(ctx)\n\tif err != nil {","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/dependencies.go#L359-L395","documentation":"GetRawClient resolves the raw-content host (raw.githubusercontent.com on dotcom, raw.<host> or <host>/raw on GHES) through the APIHostResolver before building pkg/raw's client. This wrap appears when the resolver's RawURL(ctx) errors. With utils.APIHost the raw URL is parsed once during NewAPIHost, so the error points at custom resolvers or dependency miswiring, and it disables raw-file tools such as get_file_contents fallbacks.","triggerScenarios":"deps.GetRawClient(ctx) with a custom resolver lacking a raw URL; GHES deployments where the resolver attempts subdomain-isolation detection per request and the probe fails; resolvers returning nil URL with error for environments that block raw hosts. Never triggered by the standard resolver at request time.","commonSituations":"Proxies that allow api.* but not raw.*; air-gapped GHES installs where raw.<host> is unreachable and an integrator turns that into an error; incomplete APIHostResolver implementations; fakes in tests.","solutions":["Mirror the shipped GHES logic: decide raw.<host>/ vs <host>/raw/ once at startup (utils.NewAPIHost already probes subdomain isolation) and cache the parsed URL","Do not make RawURL do network probes per request; move any reachability check to construction and degrade to a fixed path-based URL","Preflight RawURL at process init with the other four methods","If raw access is intentionally disabled, gate the tools that need GetRawClient instead of erroring at call time"],"exampleFix":"// before: per-request probe that can fail\ntype r struct{ host string }\nfunc (r r) RawURL(ctx context.Context) (*url.URL, error) {\n\tif !probeRaw(r.host) { return nil, fmt.Errorf(\"raw unreachable\") }\n\treturn url.Parse(\"https://raw.\" + r.host + \"/\")\n}\n\n// after: decide once in NewAPIHost-style constructor and return a stored URL\nfunc (x r) RawURL(context.Context) (*url.URL, error) { return x.raw, nil }","handlingStrategy":"validation","validationCode":"// preflight raw host resolution\nraw, err := apiHosts.RawURL(context.Background())\nif err != nil || raw == nil || !raw.IsAbs() {\n\tlog.Fatalf(\"raw URL unusable: %v\", err)\n}","typeGuard":"func hasValidRawURL(a utils.APIHostResolver) bool {\n\tu, err := a.RawURL(context.Background())\n\treturn err == nil && u != nil && u.IsAbs()\n}","tryCatchPattern":null,"preventionTips":["Decide raw.<host> vs <host>/raw once at startup (subdomain isolation probe belongs in NewAPIHost, not per request)","Cache the parsed raw URL in the resolver","Gate raw-content tools when the raw host is intentionally blocked"],"tags":["go","configuration","raw-content","dependency-injection"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}