gastownhall/beads · error

%s:// URL must include a hostname

Error message

%s:// URL must include a hostname

What it means

http(s) and git+http(s) remote URLs must include a hostname. After url.Parse, parsed.Host is empty for forms like "https:///path" or "https://", so the URL cannot address a server.

Source

Thrown at internal/remotecache/url.go:148

	}

	// Scheme-specific structural validation
	switch scheme {
	case "dolthub":
		// dolthub://org/repo — requires org and repo
		p := strings.TrimPrefix(parsed.Path, "/")
		host := parsed.Host
		combined := host
		if p != "" {
			combined = host + "/" + p
		}
		parts := strings.Split(combined, "/")
		if len(parts) < 2 || parts[0] == "" || parts[1] == "" {
			return fmt.Errorf("dolthub:// URL must have org/repo format (e.g., dolthub://myorg/myrepo)")
		}
	case "https", "http", "git+https", "git+http":
		if parsed.Host == "" {
			return fmt.Errorf("%s:// URL must include a hostname", scheme)
		}
	case "ssh", "git", "git+ssh":
		if parsed.Host == "" {
			return fmt.Errorf("%s:// URL must include a hostname", scheme)
		}
	case "s3", "aws", "gs":
		// s3://bucket/path, aws://bucket/path, gs://bucket/path — host is the bucket
		if parsed.Host == "" {
			return fmt.Errorf("%s:// URL must include a bucket name", scheme)
		}
	case "az":
		// az://account.blob.core.windows.net/container/path
		if parsed.Host == "" {
			return fmt.Errorf("az:// URL must include a storage account hostname")
		}
	case "oci":
		if parsed.Host == "" {
			return fmt.Errorf("oci:// URL must include a namespace or bucket host")

View on GitHub (pinned to 71377f2769)

Solutions

  1. Add the hostname: "https://example.com/org/repo"
  2. Check env/config interpolation for an empty HOST/ENDPOINT variable
  3. Use the fully qualified domain (or localhost with port) instead of a scheme-only URL

Example fix

// before
remote := "https:///org/repo"
// after
remote := "https://dolthub.com/org/repo"
Defensive patterns

Strategy: validation

Validate before calling

func hasHTTPHost(u string) bool {
	scheme, _, ok := strings.Cut(u, "://")
	if !ok || !strings.HasPrefix(scheme, "http") { return false }
	parsed, err := url.Parse(u)
	return err == nil && parsed.Host != ""
}

Type guard

func httpURLWithHost(s string) (*url.URL, bool) {
	u, err := url.Parse(s)
	if err != nil || u.Host == "" || (u.Scheme != "https" && u.Scheme != "http") {
		return nil, false
	}
	return u, true
}

Try / catch

if err := remotecache.ValidateRemoteURL(u); err != nil {
	if strings.Contains(err.Error(), "must include a hostname") {
		return fmt.Errorf("remote %q is missing a host; expected https://host/path", u)
	}
}

Prevention

When it happens

Trigger: ValidateRemoteURL with "https:///org/repo", "http://", "git+https:///repo", or a URL where the host was accidentally dropped during substitution.

Common situations: Config templates with an unfilled host variable, stripping the host when normalizing URLs, or writing relative URLs where absolute ones are required.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/16948329f1b36280. Report an issue: GitHub.