gastownhall/beads · error

remote URL scheme %q is not allowed (expected one of: %s)

Error message

remote URL scheme %q is not allowed (expected one of: %s)

What it means

The URL has a scheme, but that scheme is not in the allowlist recognized by this library (dolthub, gs, s3, aws, az, oci, file, https, http, ssh, git, git+ssh, git+https, git+http, git+file). This is a security boundary; unknown schemes are rejected before any parsing or command execution.

Source

Thrown at internal/remotecache/url.go:124

func validateSchemeURL(rawURL string) error {
	// net/url doesn't understand git+ssh:// etc., so we normalize first
	normalizedURL := rawURL
	scheme := ""
	if idx := strings.Index(rawURL, "://"); idx > 0 {
		scheme = rawURL[:idx]
		// For net/url parsing, replace git+ssh with a parseable scheme
		if strings.HasPrefix(scheme, "git+") {
			normalizedURL = rawURL[len(scheme)+3:] // strip scheme://
			normalizedURL = "placeholder://" + normalizedURL
		}
	}

	if scheme == "" {
		return fmt.Errorf("remote URL has no scheme (expected one of: %s)", strings.Join(sortedSchemes(), ", "))
	}

	if !allowedSchemes[scheme] {
		return fmt.Errorf("remote URL scheme %q is not allowed (expected one of: %s)", scheme, strings.Join(sortedSchemes(), ", "))
	}

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

View on GitHub (pinned to 71377f2769)

Solutions

  1. Correct the scheme to one of the allowed list, e.g. use "https://" instead of "ftps://"
  2. Map unsupported provider schemes to a supported one (e.g. s3a://bucket to s3://bucket)
  3. Fix typos like "httpss" or "dolt" to "https" or "dolthub"

Example fix

// before
remote := "ftp://files.example.com/repo"
// after
remote := "https://files.example.com/repo"
Defensive patterns

Strategy: validation

Validate before calling

var allowed = map[string]bool{"dolthub":true,"https":true,"http":true,"ssh":true,"git":true,"git+ssh":true,"git+https":true,"git+http":true,"git+file":true,"s3":true,"aws":true,"gs":true,"az":true,"oci":true,"file":true}
func schemeAllowed(u string) bool {
	i := strings.Index(u, "://")
	return i > 0 && allowed[u[:i]]
}

Type guard

func hasAllowedScheme(u string) bool {
	i := strings.Index(u, "://")
	return i > 0 && allowed[u[:i]]
}

Try / catch

if err := remotecache.ValidateRemoteURL(u); err != nil {
	var urlErr *url.Error
	if strings.Contains(err.Error(), "not allowed") {
		return fmt.Errorf("unsupported remote %q; supported schemes: dolthub, https, s3, gs, az, oci, file", u)
	}
	_ = urlErr
}

Prevention

When it happens

Trigger: ValidateRemoteURL with schemes like "ftp://", "ftps://", "git+ftp://", "dolt://", "blob://", or a typo like "httpss://" or "s3a://".

Common situations: Typos in scheme names, copying URLs from other tools (e.g. ftp or registry schemes), or using a cloud provider scheme (s3a, wasb) this library does not support.

Related errors


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