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
- Use utils.NewAPIHost(GITHUB_HOST) so upload URL derivation (including GHES subdomain-isolation probing) and validation happen once at startup
- If implementing APIHostResolver, make UploadURL return a pre-parsed *url.URL (e.g. https://uploads.github.com for dotcom) and never fail per request
- Preflight all five resolver methods (BaseRESTURL, GraphqlURL, UploadURL, RawURL, AuthorizationServerURL) during process init and fail fast
- 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
- Derive uploads.<host> in the same constructor that parses the base host
- Preflight all five APIHostResolver methods at startup
- Disable or gate upload-dependent tools if your gateway cannot reach the uploads host
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
- failed to get base REST URL: %w
- failed to get GraphQL URL: %w
- failed to get Raw URL: %w
- failed to get GitHub client: %w
- GitHub App authentication and OAuth login (--oauth-client-id
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/7a3b64cc183b2bd5.
Report an issue: GitHub.