gastownhall/beads · error

dolthub:// URL must have org/repo format (e.g., dolthub://my

Error message

dolthub:// URL must have org/repo format (e.g., dolthub://myorg/myrepo)

What it means

dolthub:// URLs must identify both an organization and a repository (dolthub://org/repo). After parsing, the host and path are combined and split on "/"; if there are fewer than two non-empty segments, the URL lacks an org, a repo, or both.

Source

Thrown at internal/remotecache/url.go:144

	parsed, err := url.Parse(normalizedURL)
	if err != nil {
		return fmt.Errorf("remote URL is malformed: %w", err)
	}

	// 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")

View on GitHub (pinned to 71377f2769)

Solutions

  1. Include both org and repo: "dolthub://myorg/myrepo"
  2. Check that config/env substitution didn't truncate the URL at the slash
  3. If only browsing an org, use the Dolthub website — the remote URL must name a specific repo

Example fix

// before
remote := "dolthub://myorg/"
// after
remote := "dolthub://myorg/myrepo"
Defensive patterns

Strategy: validation

Validate before calling

func validDolthubURL(u string) bool {
	rest, ok := strings.CutPrefix(u, "dolthub://")
	if !ok { return false }
	parts := strings.Split(strings.Trim(rest, "/"), "/")
	return len(parts) >= 2 && parts[0] != "" && parts[1] != ""
}

Type guard

func isDolthubOrgRepo(u string) bool {
	const p = "dolthub://"
	if !strings.HasPrefix(u, p) { return false }
	parts := strings.Split(strings.Trim(u[len(p):], "/"), "/")
	return len(parts) >= 2 && parts[0] != "" && parts[1] != ""
}

Try / catch

if err := remotecache.ValidateRemoteURL(u); err != nil {
	if strings.Contains(err.Error(), "org/repo format") {
		return fmt.Errorf("dolthub remote %q must be dolthub://org/repo", u)
	}
}

Prevention

When it happens

Trigger: ValidateRemoteURL with "dolthub://", "dolthub://myorg", "dolthub://myorg/", or "dolthub:///myrepo" — any form missing host-and-path org/repo segments.

Common situations: Config truncated at paste time, environment variables set to just the org, or templating that dropped the repo part of the URL.

Related errors


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