github/github-mcp-server · error
failed to get Raw URL: %w
Error message
failed to get Raw URL: %w
What it means
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.
Source
Thrown at pkg/github/dependencies.go:377
graphqlURL, err := d.apiHosts.GraphqlURL(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get GraphQL URL: %w", err)
}
gqlClient := githubv4.NewEnterpriseClient(graphqlURL.String(), gqlHTTPClient)
return gqlClient, nil
}
// GetRawClient implements ToolDependencies.
func (d *RequestDeps) GetRawClient(ctx context.Context) (*raw.Client, error) {
client, err := d.GetClient(ctx)
if err != nil {
return nil, err
}
rawURL, err := d.apiHosts.RawURL(ctx)
if err != nil {
return nil, fmt.Errorf("failed to get Raw URL: %w", err)
}
rawClient, err := raw.NewClient(client, rawURL)
if err != nil {
return nil, fmt.Errorf("failed to create raw client: %w", err)
}
return rawClient, nil
}
// GetRepoAccessCache implements ToolDependencies.
func (d *RequestDeps) GetRepoAccessCache(ctx context.Context) (*lockdown.RepoAccessCache, error) {
if !d.lockdownMode {
return nil, nil
}
gqlClient, err := d.GetGQLClient(ctx)
if err != nil {View on GitHub (pinned to 0ea1f775a7)
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
Example fix
// before: per-request probe that can fail
type r struct{ host string }
func (r r) RawURL(ctx context.Context) (*url.URL, error) {
if !probeRaw(r.host) { return nil, fmt.Errorf("raw unreachable") }
return url.Parse("https://raw." + r.host + "/")
}
// after: decide once in NewAPIHost-style constructor and return a stored URL
func (x r) RawURL(context.Context) (*url.URL, error) { return x.raw, nil } Defensive patterns
Strategy: validation
Validate before calling
// preflight raw host resolution
raw, err := apiHosts.RawURL(context.Background())
if err != nil || raw == nil || !raw.IsAbs() {
log.Fatalf("raw URL unusable: %v", err)
} Type guard
func hasValidRawURL(a utils.APIHostResolver) bool {
u, err := a.RawURL(context.Background())
return err == nil && u != nil && u.IsAbs()
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- failed to get base REST URL: %w
- failed to get upload URL: %w
- failed to get GraphQL URL: %w
- GitHub App authentication and OAuth login (--oauth-client-id
- GitHub App installation ID is required (GITHUB_APP_INSTALLAT
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/225e3cbf0c3e814f.
Report an issue: GitHub.