gastownhall/beads · error

%s:// URL must include a bucket name

Error message

%s:// URL must include a bucket name

What it means

For s3, aws, and gs URLs the hostname portion is the bucket name (s3://bucket/path). If parsed.Host is empty, no bucket was specified and the URL cannot address cloud storage.

Source

Thrown at internal/remotecache/url.go:157

		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")
		}
	case "file":
		// file:// is allowed with any path
	case "git+file":
		// git+file:// is Dolt's normalized form for local git remotes.
	}

	return nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Put the bucket in the host position: "s3://my-bucket/path"
  2. Check that the BUCKET env/config variable is populated
  3. Verify the URL is not s3:///bucket/path — the third slash means an empty host

Example fix

// before
remote := "s3:///my-bucket/db"
// after
remote := "s3://my-bucket/db"
Defensive patterns

Strategy: validation

Validate before calling

func validCloudStoreURL(u string) bool {
	scheme, rest, ok := strings.Cut(u, "://")
	if !ok { return false }
	switch scheme { case "s3", "aws", "gs": default: return false }
	host := rest
	if i := strings.Index(rest, "/"); i >= 0 { host = rest[:i] }
	return host != ""
}

Type guard

func cloudURLWithBucket(s string) (bucket string, ok bool) {
	i := strings.Index(s, "://")
	if i < 0 { return "", false }
	rest := s[i+3:]
	if j := strings.Index(rest, "/"); j >= 0 { rest = rest[:j] }
	return rest, rest != ""
}

Try / catch

if err := remotecache.ValidateRemoteURL(u); err != nil {
	if strings.Contains(err.Error(), "must include a bucket name") {
		return fmt.Errorf("cloud remote %q missing bucket; use s3://bucket/path", u)
	}
}

Prevention

When it happens

Trigger: ValidateRemoteURL with "s3://", "s3:///prefix/path", "gs://", or "aws:///bucket" — bucket name missing or misplaced in the path.

Common situations: Env-var substitution leaving BUCKET empty, putting the bucket in the path (s3:///bucket/key), or forgetting the bucket when hand-writing cloud remote URLs.

Related errors


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