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

  1. 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
  2. Do not make RawURL do network probes per request; move any reachability check to construction and degrade to a fixed path-based URL
  3. Preflight RawURL at process init with the other four methods
  4. 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

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


AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15). Data as JSON: /api/errors/225e3cbf0c3e814f. Report an issue: GitHub.