github/github-mcp-server · error

failed to get upload URL: %w

Error message

failed to get upload URL: %w

What it means

RequestDeps.GetClient resolves the uploads URL (used for release-asset uploads) through the injected utils.APIHostResolver before constructing the REST client. With the bundled utils.APIHost the uploads URL is parsed once in NewAPIHost (dotcom, GHEC, or GHES with/without subdomain isolation), so UploadURL never errors; this wrap appears only with custom resolvers or miswired dependency structs. It aborts every REST-based tool call until fixed.

Source

Thrown at pkg/github/dependencies.go:322

	}
}

// GetClient implements ToolDependencies.
func (d *RequestDeps) GetClient(ctx context.Context) (*gogithub.Client, error) {
	// extract the token from the context
	tokenInfo, ok := ghcontext.GetTokenInfo(ctx)
	if !ok {
		return nil, fmt.Errorf("no token info in context")
	}
	token := tokenInfo.Token

	baseRestURL, err := d.apiHosts.BaseRESTURL(ctx)
	if err != nil {
		return nil, fmt.Errorf("failed to get base REST URL: %w", err)
	}
	uploadURL, err := d.apiHosts.UploadURL(ctx)
	if err != nil {
		return nil, fmt.Errorf("failed to get upload URL: %w", err)
	}

	// Construct REST client
	restClient, err := gogithub.NewClient(
		gogithub.WithAuthToken(token),
		gogithub.WithUserAgent(fmt.Sprintf("github-mcp-server/%s", d.version)),
		gogithub.WithEnterpriseURLs(baseRestURL.String(), uploadURL.String()),
	)
	if err != nil {
		return nil, fmt.Errorf("failed to create REST client: %w", err)
	}
	return restClient, nil
}

// GetGQLClient implements ToolDependencies.
func (d *RequestDeps) GetGQLClient(ctx context.Context) (*githubv4.Client, error) {
	// extract the token from the context
	tokenInfo, ok := ghcontext.GetTokenInfo(ctx)

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Use utils.NewAPIHost(GITHUB_HOST) so upload URL derivation (including GHES subdomain-isolation probing) and validation happen once at startup
  2. If implementing APIHostResolver, make UploadURL return a pre-parsed *url.URL (e.g. https://uploads.github.com for dotcom) and never fail per request
  3. Preflight all five resolver methods (BaseRESTURL, GraphqlURL, UploadURL, RawURL, AuthorizationServerURL) during process init and fail fast
  4. For upload-dependent tools only, consider resolving lazily but caching the result so a transient resolver error surfaces once, not per call

Example fix

// before
type r struct{}
func (r) UploadURL(ctx context.Context) (*url.URL, error) {
	return nil, fmt.Errorf("uploads not configured") // every GetClient fails
}

// after: derive and cache at construction
type r struct{ upload *url.URL }
func newR(base string) (*r, error) {
	u, err := url.Parse(base) // e.g. https://uploads.github.com
	if err != nil {
		return nil, err
	}
	return &r{upload: u}, nil
}
func (x r) UploadURL(context.Context) (*url.URL, error) { return x.upload, nil }
Defensive patterns

Strategy: validation

Validate before calling

// preflight the uploads URL before serving traffic
up, err := apiHosts.UploadURL(context.Background())
if err != nil || up == nil || !up.IsAbs() {
	log.Fatalf("uploads URL unusable: %v", err)
}

Type guard

func hasValidUploadURL(a utils.APIHostResolver) bool {
	u, err := a.UploadURL(context.Background())
	return err == nil && u != nil && u.IsAbs()
}

Prevention

When it happens

Trigger: deps.GetClient(ctx) with a custom APIHostResolver whose UploadURL(ctx) errors, or a resolver built without an uploads URL (returning nil URL and an error). GHES setups hit URL-derivation bugs only at NewAPIHost time (startup), not here. Standard utils.NewAPIHost never produces this at request time.

Common situations: Library integrators implementing APIHostResolver for an internal gateway and forgetting the uploads endpoint; proxies that only front api.* and not uploads.*; test fakes with stub UploadURL returning errors; upgrading utils.APIHostResolver interface signature and missing implementations.

Related errors


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