charmbracelet/crush · error

invalid server host: %v

Error message

invalid server host: %v

What it means

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.

Source

Thrown at internal/cmd/server.go:47

	Short: "Start the Crush server",
	RunE: func(cmd *cobra.Command, _ []string) error {
		dataDir, err := cmd.Flags().GetString("data-dir")
		if err != nil {
			return fmt.Errorf("failed to get data directory: %v", err)
		}
		debug, err := cmd.Flags().GetBool("debug")
		if err != nil {
			return fmt.Errorf("failed to get debug flag: %v", err)
		}

		cfg, err := config.Load(config.GlobalWorkspaceDir(), dataDir, debug)
		if err != nil {
			return fmt.Errorf("failed to load configuration: %v", err)
		}

		hostURL, err := server.ParseHostURL(serverHost)
		if err != nil {
			return fmt.Errorf("invalid server host: %v", err)
		}

		logFile := filepath.Join(config.GlobalCacheDir(), "server-"+safeHostName(hostURL), "crush.log")

		if term.IsTerminal(os.Stderr.Fd()) {
			crushlog.Setup(logFile, debug, os.Stderr)
		} else {
			crushlog.Setup(logFile, debug)
		}

		srv := server.NewServer(cfg, hostURL.Scheme, hostURL.Host)
		srv.SetLogger(slog.Default())
		slog.Info("Starting Crush server...", "addr", serverHost)

		errch := make(chan error, 1)
		sigch := make(chan os.Signal, 1)
		sigs := []os.Signal{os.Interrupt}
		sigs = append(sigs, addSignals(sigs)...)

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Use a plain `host:port` value, e.g. `--host localhost:8080`.
  2. Check the expansion of any env var used for the host (`echo $CRUSH_HOST`) — it may be empty.
  3. Quote the value in scripts to avoid shell splitting/interpolation issues.
  4. Wrap IPv6 literals in brackets, e.g. `[::1]:8080`.
  5. Omit --host entirely to use the default host URL.

Example fix

// before
crush server --host localhost:99999    # invalid port
// after
crush server --host localhost:8080
Defensive patterns

Strategy: validation

Validate before calling

host := os.Getenv("CRUSH_HOST")
if host != "" {
    if _, err := server.ParseHostURL(host); err != nil {
        return fmt.Errorf("CRUSH_HOST=%q is not a valid host:port", host)
    }
}

Try / catch

hostURL, err := server.ParseHostURL(serverHost)
if err != nil {
    return fmt.Errorf("invalid server host: %v", err) // surface the parse detail
}

Prevention

When it happens

Trigger: 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`).

Common situations: 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.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/bb4c624eea4328e8. Report an issue: GitHub.