github/github-mcp-server · error

failed to create raw client: %w

Error message

failed to create raw client: %w

What it means

After resolving the raw URL, GetRawClient calls raw.NewClient(client, rawURL), which internally runs gogithub.NewClient(WithEnterpriseURLs(rawURL.String(), rawURL.String())). If that string cannot be re-parsed as an absolute URL, go-github errors and this wrap is returned. Since rawURL arrives as a parsed *url.URL, failure implies a resolver that produces degenerate URL objects (relative, empty, or scheme-less) or a nil-ish URL whose String() is unusable.

Source

Thrown at pkg/github/dependencies.go:382

	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 {
		return nil, err
	}

	restClient, err := d.GetClient(ctx)
	if err != nil {

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Log rawURL.String() right before client construction to see the exact string go-github rejects
  2. Ensure the resolver returns an absolute URL: scheme https, populated Host, and Path built via JoinPath rather than concatenation
  3. Preserve host:port authorities when deriving raw URLs (mirror newGHESHost's use of u.Host)
  4. Unit-test the resolver: assert u.IsAbs() and u.Host != "" for RawURL output before wiring it into RequestDeps

Example fix

// before
rawURL := &url.URL{Host: "raw.example.com"} // no scheme -> String() = "raw.example.com"
rawClient, err := raw.NewClient(client, rawURL) // WithEnterpriseURLs fails

// after
rawURL := &url.URL{Scheme: "https", Host: host, Path: "/"}
if !rawURL.IsAbs() || rawURL.Host == "" {
	return nil, fmt.Errorf("raw URL must be absolute: %s", rawURL)
}
rawClient, err := raw.NewClient(client, rawURL)
Defensive patterns

Strategy: validation

Validate before calling

// reject degenerate URLs before raw.NewClient
if rawURL == nil || !rawURL.IsAbs() || rawURL.Host == "" {
	return fmt.Errorf("raw URL must be absolute with a host, got %v", rawURL)
}

Type guard

func isUsableRawURL(u *url.URL) bool {
	return u != nil && u.IsAbs() && u.Host != "" && u.Scheme == "https"
}

Try / catch

rawClient, err := raw.NewClient(client, rawURL)
if err != nil {
	return nil, fmt.Errorf("failed to create raw client: %w", err) // wrapped go-github url.Parse error
}

Prevention

When it happens

Trigger: A custom RawURL returning &url.URL{Path: "/raw/"} (no scheme/host) so String() yields "/raw/"; URLs whose Host contains invalid characters; constructed URL structs with Opaque set producing non-standard strings; a resolver returning a URL built from unvalidated tenant input. The standard utils.APIHost never produces such strings.

Common situations: Library integrators building *url.URL literals by hand; string-concatenated raw hosts with unencoded characters; GHES hosts with ports where the authority is dropped (the shipped code explicitly preserves u.Host for this reason); version drift in go-github URL validation.

Related errors


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