{"record":{"id":"bb4c624eea4328e8","repo":"charmbracelet/crush","slug":"invalid-server-host-v","errorCode":null,"errorMessage":"invalid server host: %v","messagePattern":"invalid server host: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cmd/server.go","lineNumber":47,"sourceCode":"\tShort: \"Start the Crush server\",\n\tRunE: func(cmd *cobra.Command, _ []string) error {\n\t\tdataDir, err := cmd.Flags().GetString(\"data-dir\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to get data directory: %v\", err)\n\t\t}\n\t\tdebug, err := cmd.Flags().GetBool(\"debug\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to get debug flag: %v\", err)\n\t\t}\n\n\t\tcfg, err := config.Load(config.GlobalWorkspaceDir(), dataDir, debug)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to load configuration: %v\", err)\n\t\t}\n\n\t\thostURL, err := server.ParseHostURL(serverHost)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"invalid server host: %v\", err)\n\t\t}\n\n\t\tlogFile := filepath.Join(config.GlobalCacheDir(), \"server-\"+safeHostName(hostURL), \"crush.log\")\n\n\t\tif term.IsTerminal(os.Stderr.Fd()) {\n\t\t\tcrushlog.Setup(logFile, debug, os.Stderr)\n\t\t} else {\n\t\t\tcrushlog.Setup(logFile, debug)\n\t\t}\n\n\t\tsrv := server.NewServer(cfg, hostURL.Scheme, hostURL.Host)\n\t\tsrv.SetLogger(slog.Default())\n\t\tslog.Info(\"Starting Crush server...\", \"addr\", serverHost)\n\n\t\terrch := make(chan error, 1)\n\t\tsigch := make(chan os.Signal, 1)\n\t\tsigs := []os.Signal{os.Interrupt}\n\t\tsigs = append(sigs, addSignals(sigs)...)","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/cmd/server.go#L29-L65","documentation":"The server command parses the --host value with server.ParseHostURL to obtain the listen URL. If the host string is not a valid host:port / URL form, it returns \"invalid server host\". The wrapped inner error details what was wrong with the format.","triggerScenarios":"Running `crush server --host` with a malformed value: missing scheme, illegal characters, empty string when a host is required, or an unparseable port (e.g. `--host localhost:99999`).","commonSituations":"Typos like `--host http:/localhost:8080` (single slash), shell variables expanding to empty, IPv6 addresses needing brackets, or copying a host from another tool's config format.","solutions":["Use a plain `host:port` value, e.g. `--host localhost:8080`.","Check the expansion of any env var used for the host (`echo $CRUSH_HOST`) — it may be empty.","Quote the value in scripts to avoid shell splitting/interpolation issues.","Wrap IPv6 literals in brackets, e.g. `[::1]:8080`.","Omit --host entirely to use the default host URL."],"exampleFix":"// before\ncrush server --host localhost:99999    # invalid port\n// after\ncrush server --host localhost:8080","handlingStrategy":"validation","validationCode":"host := os.Getenv(\"CRUSH_HOST\")\nif host != \"\" {\n    if _, err := server.ParseHostURL(host); err != nil {\n        return fmt.Errorf(\"CRUSH_HOST=%q is not a valid host:port\", host)\n    }\n}","typeGuard":null,"tryCatchPattern":"hostURL, err := server.ParseHostURL(serverHost)\nif err != nil {\n    return fmt.Errorf(\"invalid server host: %v\", err) // surface the parse detail\n}","preventionTips":["Use the `host:port` form; wrap IPv6 literals in brackets.","Echo shell variables before passing them to --host to catch empty expansions.","Quote --host values in scripts to prevent word splitting.","Omit --host to fall back to the default when unsure of the format."],"tags":["cli","server","configuration"],"backgroundTag":"invalid-host-url","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}