{"record":{"id":"eb6f5d2a2dc31353","repo":"gastownhall/beads","slug":"remote-url-scheme-q-is-not-allowed-expected-one","errorCode":null,"errorMessage":"remote URL scheme %q is not allowed (expected one of: %s)","messagePattern":"remote URL scheme %q is not allowed \\(expected one of: (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/remotecache/url.go","lineNumber":124,"sourceCode":"func validateSchemeURL(rawURL string) error {\n\t// net/url doesn't understand git+ssh:// etc., so we normalize first\n\tnormalizedURL := rawURL\n\tscheme := \"\"\n\tif idx := strings.Index(rawURL, \"://\"); idx > 0 {\n\t\tscheme = rawURL[:idx]\n\t\t// For net/url parsing, replace git+ssh with a parseable scheme\n\t\tif strings.HasPrefix(scheme, \"git+\") {\n\t\t\tnormalizedURL = rawURL[len(scheme)+3:] // strip scheme://\n\t\t\tnormalizedURL = \"placeholder://\" + normalizedURL\n\t\t}\n\t}\n\n\tif scheme == \"\" {\n\t\treturn fmt.Errorf(\"remote URL has no scheme (expected one of: %s)\", strings.Join(sortedSchemes(), \", \"))\n\t}\n\n\tif !allowedSchemes[scheme] {\n\t\treturn fmt.Errorf(\"remote URL scheme %q is not allowed (expected one of: %s)\", scheme, strings.Join(sortedSchemes(), \", \"))\n\t}\n\n\tparsed, err := url.Parse(normalizedURL)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"remote URL is malformed: %w\", err)\n\t}\n\n\t// Scheme-specific structural validation\n\tswitch scheme {\n\tcase \"dolthub\":\n\t\t// dolthub://org/repo — requires org and repo\n\t\tp := strings.TrimPrefix(parsed.Path, \"/\")\n\t\thost := parsed.Host\n\t\tcombined := host\n\t\tif p != \"\" {\n\t\t\tcombined = host + \"/\" + p\n\t\t}\n\t\tparts := strings.Split(combined, \"/\")","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/remotecache/url.go#L106-L142","documentation":"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.","triggerScenarios":"ValidateRemoteURL with schemes like \"ftp://\", \"ftps://\", \"git+ftp://\", \"dolt://\", \"blob://\", or a typo like \"httpss://\" or \"s3a://\".","commonSituations":"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.","solutions":["Correct the scheme to one of the allowed list, e.g. use \"https://\" instead of \"ftps://\"","Map unsupported provider schemes to a supported one (e.g. s3a://bucket to s3://bucket)","Fix typos like \"httpss\" or \"dolt\" to \"https\" or \"dolthub\""],"exampleFix":"// before\nremote := \"ftp://files.example.com/repo\"\n// after\nremote := \"https://files.example.com/repo\"","handlingStrategy":"validation","validationCode":"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}\nfunc schemeAllowed(u string) bool {\n\ti := strings.Index(u, \"://\")\n\treturn i > 0 && allowed[u[:i]]\n}","typeGuard":"func hasAllowedScheme(u string) bool {\n\ti := strings.Index(u, \"://\")\n\treturn i > 0 && allowed[u[:i]]\n}","tryCatchPattern":"if err := remotecache.ValidateRemoteURL(u); err != nil {\n\tvar urlErr *url.Error\n\tif strings.Contains(err.Error(), \"not allowed\") {\n\t\treturn fmt.Errorf(\"unsupported remote %q; supported schemes: dolthub, https, s3, gs, az, oci, file\", u)\n\t}\n\t_ = urlErr\n}","preventionTips":["Keep a shared constant list of supported schemes and validate against it at config load","Normalize provider-specific aliases (s3a->s3) before validation","Log the scheme list in user-facing docs/errors"],"tags":["url-validation","scheme","allowlist"],"backgroundTag":"unsupported-url-scheme","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}