{"record":{"id":"f66234968dd94338","repo":"github/github-mcp-server","slug":"failed-to-parse-api-host-w-f66234","errorCode":null,"errorMessage":"failed to parse API host: %w","messagePattern":"failed to parse API host: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/http/server.go","lineNumber":130,"sourceCode":"\tvar slogHandler slog.Handler\n\tvar logOutput io.Writer\n\tif cfg.LogFilePath != \"\" {\n\t\tfile, err := os.OpenFile(cfg.LogFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to open log file: %w\", err)\n\t\t}\n\t\tlogOutput = file\n\t\tslogHandler = slog.NewTextHandler(logOutput, &slog.HandlerOptions{Level: slog.LevelDebug})\n\t} else {\n\t\tlogOutput = os.Stderr\n\t\tslogHandler = slog.NewTextHandler(logOutput, &slog.HandlerOptions{Level: slog.LevelInfo})\n\t}\n\tlogger := slog.New(slogHandler)\n\tlogger.Info(\"starting server\", \"version\", cfg.Version, \"host\", cfg.Host, \"lockdownEnabled\", cfg.LockdownMode, \"readOnly\", cfg.ReadOnly, \"insidersMode\", cfg.InsidersMode)\n\n\tapiHost, err := utils.NewAPIHost(cfg.Host)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to parse API host: %w\", err)\n\t}\n\thostType, err := utils.ParseHostType(cfg.Host)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to classify API host: %w\", err)\n\t}\n\n\trepoAccessOpts := []lockdown.RepoAccessOption{\n\t\tlockdown.WithLogger(logger.With(\"component\", \"lockdown\")),\n\t}\n\tif cfg.RepoAccessCacheTTL != nil {\n\t\trepoAccessOpts = append(repoAccessOpts, lockdown.WithTTL(*cfg.RepoAccessCacheTTL))\n\t}\n\n\tfeatureChecker := createHTTPFeatureChecker(cfg.EnabledFeatures, cfg.InsidersMode)\n\n\tobs, err := observability.NewExporters(logger, metrics.NewNoopMetrics())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create observability exporters: %w\", err)","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/http/server.go#L112-L148","documentation":"utils.NewAPIHost rejected cfg.Host: the string could not be parsed and normalized into the REST/GraphQL/upload/raw endpoint set. Hosts must be parseable URLs with a scheme - the dotcom constant or a GHES base URL.","triggerScenarios":"Passing a bare hostname without a scheme (github.example.com), a URL with unexpected path/query components, control characters, or otherwise malformed URL syntax.","commonSituations":"Misconfigured GITHUB_API_URL or host flag values; copy-paste with trailing punctuation or whitespace; switching from hostname-style config to URL-style config.","solutions":["Use https://api.github.com for dotcom, or the full https base URL of the GHES instance","Ensure the scheme is present and there is no stray path, query, or whitespace","Validate candidate host strings with utils.NewAPIHost in a smoke test before deploying"],"exampleFix":"// before\ncfg.Host = \"github.example.com\"\n\n// after\ncfg.Host = \"https://github.example.com\"","handlingStrategy":"validation","validationCode":"u, err := url.Parse(cfg.Host)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n\treturn fmt.Errorf(\"host must be an absolute URL like https://api.github.com, got %q\", cfg.Host)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure hosts as absolute https URLs","Trim whitespace and quotes from env-provided host values","Validate host strings with utils.NewAPIHost in config tests"],"tags":["configuration","url-parsing"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}