gastownhall/beads · error
SCP-style URL must be in user@host:path format
Error message
SCP-style URL must be in user@host:path format
What it means
SCP-style remote URLs must look like user@host:path. This error guards validateSCPURL's invariants: it runs only after gitSSHPattern matched, so in practice the pattern already guarantees "@" and ":" are present and this branch is defensive/unreachable for normal input — but if reached, the string lacked an @ or a colon after it.
Source
Thrown at internal/remotecache/url.go:184
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
}
// validateSCPURL validates an SCP-style URL (user@host:path)
func validateSCPURL(rawURL string) error {
// Already matched gitSSHPattern, so structure is valid.
// Extract host and verify no control chars (already checked above).
atIdx := strings.Index(rawURL, "@")
colonIdx := strings.Index(rawURL[atIdx:], ":")
if atIdx < 0 || colonIdx < 0 {
return fmt.Errorf("SCP-style URL must be in user@host:path format")
}
return nil
}
// ValidateRemoteName checks that a remote name is safe for use as a Dolt
// remote identifier. Names must start with a letter and contain only
// alphanumeric characters, hyphens, and underscores. Max 64 characters.
func ValidateRemoteName(name string) error {
if name == "" {
return fmt.Errorf("remote name cannot be empty")
}
if len(name) > 64 {
return fmt.Errorf("remote name too long (max 64 characters)")
}
if strings.HasPrefix(name, "-") {
return fmt.Errorf("remote name must not start with a dash")
}
if !validRemoteNameRegex.MatchString(name) {View on GitHub (pinned to 71377f2769)
Solutions
- Use the full SCP form: "git@github.com:org/repo.git"
- If you prefer scheme syntax, use "ssh://git@github.com/org/repo.git" instead
- Remember the separator after the host is a colon, not a slash
Example fix
// before remote := "git@github.com/org/repo" // after remote := "git@github.com:org/repo"
Defensive patterns
Strategy: validation
Validate before calling
var scpRe = regexp.MustCompile(`^[^@\s]+@[^@\s:]+:.+$`)
func validSCPForm(u string) bool { return scpRe.MatchString(u) }
// check before passing to ValidateRemoteURL Type guard
func isSCPStyle(s string) bool {
return regexp.MustCompile(`^[a-zA-Z0-9._-]+@[a-zA-Z0-9][a-zA-Z0-9._-]*:[^\x00-\x1f\x7f]+$`).MatchString(s)
} Try / catch
if err := remotecache.ValidateRemoteURL(u); err != nil {
if strings.Contains(err.Error(), "user@host:path") {
return fmt.Errorf("remote %q must be git@host:path or ssh://host/path", u)
}
} Prevention
- Always use the colon separator after the host in SCP-style remotes
- Prefer ssh:// scheme URLs, which are validated more predictably
- Run the gitSSHPattern regex on user input before submitting
When it happens
Trigger: ValidateRemoteURL with an SCP-shaped string missing "@" or missing ":" after the host. Because gitSSHPattern requires both, this is only reachable if the pattern and this check diverge (e.g. future pattern changes).
Common situations: Typing a git remote without the colon separator ("git@example.com/path") or without the user part, expecting it to be accepted as SSH.
Related errors
- remote URL has no scheme (expected one of: %s)
- dolthub:// URL must have org/repo format (e.g., dolthub://my
- 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/145c16ba5a2709c7.
Report an issue: GitHub.