{"record":{"id":"a6d80483dfe22876","repo":"github/github-mcp-server","slug":"failed-to-classify-api-host-w-a6d804","errorCode":null,"errorMessage":"failed to classify API host: %w","messagePattern":"failed to classify API host: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/http/server.go","lineNumber":134,"sourceCode":"\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)\n\t}\n\n\tdeps := github.NewRequestDeps(\n\t\tapiHost,","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/http/server.go#L116-L152","documentation":"utils.ParseHostType could not classify cfg.Host as dotcom, GHEC, or GHES. It errors only when url.Parse fails or the parsed URL has an empty scheme - i.e. the host string is not an absolute http(s) URL.","triggerScenarios":"Host string without a scheme ('api.github.com.', 'github.corp'); unparseable URL syntax; host taken from an env var that includes quotes or spaces.","commonSituations":"GHES deployments configured with a bare hostname; config templating that strips or mangles the scheme; the same misconfigurations that trigger the NewAPIHost failure one line above.","solutions":["Prefix the host with https:// (or http:// for local testing)","Verify the env/flag value for the host is an absolute URL with no surrounding whitespace or quotes","Add a startup config check that runs ParseHostType before the server boots"],"exampleFix":"// before\ncfg.Host = os.Getenv(\"GH_HOST\") // \"github.corp.example\"\n\n// after\ncfg.Host = url.PathEscape(os.Getenv(\"GH_HOST\"))\nif !strings.Contains(cfg.Host, \"://\") {\n\tcfg.Host = \"https://\" + cfg.Host\n}","handlingStrategy":"validation","validationCode":"if _, err := utils.ParseHostType(cfg.Host); err != nil {\n\t// normalize before boot: default to dotcom or prefix a scheme\n\tif cfg.Host == \"\" {\n\t\tcfg.Host = \"https://api.github.com\"\n\t} else if !strings.Contains(cfg.Host, \"://\") {\n\t\tcfg.Host = \"https://\" + cfg.Host\n\t}\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include the scheme in host configuration","Validate hosts with ParseHostType at config load time, not first request","Watch for config templating that strips URL schemes"],"tags":["configuration","url-parsing"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}