{"record":{"id":"c6581794b8769023","repo":"github/github-mcp-server","slug":"creating-installation-token-request-w","errorCode":null,"errorMessage":"creating installation token request: %w","messagePattern":"creating installation token request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/githubapp/githubapp.go","lineNumber":141,"sourceCode":"}\n\nfunc (s *installationTokenSource) Token() (*oauth2.Token, error) {\n\tjwt, err := mintJWT(s.cfg.AppID, s.privateKey, time.Now())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tendpoint, err := url.JoinPath(s.cfg.BaseRESTURL, \"app\", \"installations\", s.cfg.InstallationID, \"access_tokens\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"building installation token URL: %w\", err)\n\t}\n\n\tctx, cancel := context.WithTimeout(context.Background(), httpTimeout)\n\tdefer cancel()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating installation token request: %w\", err)\n\t}\n\treq.Header.Set(\"Authorization\", \"Bearer \"+jwt)\n\treq.Header.Set(\"Accept\", \"application/vnd.github+json\")\n\treq.Header.Set(\"X-GitHub-Api-Version\", \"2022-11-28\")\n\n\tresp, err := s.httpClient.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"requesting installation token: %w\", err)\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tif resp.StatusCode != http.StatusCreated {\n\t\tsnippet, readErr := io.ReadAll(io.LimitReader(resp.Body, 512))\n\t\tif readErr != nil {\n\t\t\treturn nil, fmt.Errorf(\"installation token request failed: %s (reading response: %w)\", resp.Status, readErr)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"installation token request failed: %s: %s\", resp.Status, strings.TrimSpace(string(snippet)))\n\t}","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/internal/githubapp/githubapp.go#L123-L159","documentation":"http.NewRequestWithContext rejected the endpoint URL built from BaseRESTURL. NewRequestWithContext calls url.Parse on the final joined string, so it fails only when the URL is still unparseable — a base that survived JoinPath but contains characters the stricter request parser rejects, or an empty URL after joining. Like error 102 this is a configuration-shape failure that occurs before any socket is opened.","triggerScenarios":"The joined endpoint string (e.g. BaseRESTURL + 'app/installations/{id}/access_tokens') contains a control character (0x7f, raw newline), a space in the host, or InstallationID text that makes the path invalid, causing http.NewRequestWithContext at internal/githubapp/githubapp.go:139 to return a parse error.","commonSituations":"BaseRESTURL loaded from a .env file with embedded CR (\r) from Windows line endings; an InstallationID taken from user input containing spaces or '%zz' malformed escapes; a config value that is actually empty after JoinPath normalization.","solutions":["Sanitize BaseRESTURL and InstallationID (strip CR/LF/spaces) before building the Config","Confirm InstallationID is digits-only — GitHub installation IDs are numeric strings","Validate the final URL with url.ParseRequestURI in a startup check to catch this before first token refresh"],"exampleFix":"// before\ninstallationID := rawUserInput // \" 42\r\" -> creating installation token request: ...\n\n// after\ninstallationID := strings.TrimSpace(rawUserInput)\nif !regexp.MustCompile(`^[0-9]+$`).MatchString(installationID) {\n    return errors.New(\"installation ID must be numeric\")\n}","handlingStrategy":"validation","validationCode":"func validInstallationID(s string) bool { return regexp.MustCompile(`^[0-9]+$`).MatchString(s) }\n\n// and before building Config:\nif _, err := url.ParseRequestURI(base); err != nil { return err }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat installation IDs as numeric-only at every input boundary (flags, env, config files)","Strip CR/LF from config values loaded from Windows-authored files"],"tags":["configuration","url","validation","startup"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}