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
- Include both org and repo: "dolthub://myorg/myrepo"
- Check that config/env substitution didn't truncate the URL at the slash
- 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
- Build dolthub URLs with fmt.Sprintf("dolthub://%s/%s", org, repo)
- Validate org and repo are non-empty before formatting
- Add a unit test for the org/repo URL builder
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
- remote URL has no scheme (expected one of: %s)
- SCP-style URL must be in user@host:path format
- remote URL scheme %q is not allowed (expected one of: %s)
- %s:// URL must include a hostname
- %s:// URL must include a bucket name
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/64741e420672aab5.
Report an issue: GitHub.