golang-migrate/migrate · error
invalid repo
Error message
invalid repo
What it means
ErrInvalidRepo is returned by Open when the URL path yields no repo segment after trimming slashes. The driver splits u.Path on '/' and requires at least one element to use as the repo slug. In practice a URL with no path (e.g. `bitbucket://user:pass@owner`) triggers it. Exported sentinel error.
Source
Thrown at source/bitbucket/bitbucket.go:23
"io"
nurl "net/url"
"os"
"path"
"path/filepath"
"strings"
"github.com/golang-migrate/migrate/v4/source"
"github.com/ktrysmt/go-bitbucket"
)
func init() {
source.Register("bitbucket", &Bitbucket{})
}
var (
ErrNoUserInfo = fmt.Errorf("no username:password provided")
ErrNoAccessToken = fmt.Errorf("no password/app password")
ErrInvalidRepo = fmt.Errorf("invalid repo")
ErrInvalidBitbucketClient = fmt.Errorf("expected *bitbucket.Client")
ErrNoDir = fmt.Errorf("no directory")
)
type Bitbucket struct {
config *Config
client *bitbucket.Client
migrations *source.Migrations
}
type Config struct {
Owner string
Repo string
Path string
Ref string
}
func (b *Bitbucket) Open(url string) (source.Driver, error) {View on GitHub (pinned to 01a9643f14)
Solutions
- Format the URL as `bitbucket://user:pass@owner/repo/path#ref` — owner is the host, repo is the first path segment.
- Add the missing repo segment to the URL in your config.
- Check the interpolated value of the repo variable before building the URL.
- Validate the URL with net/url.Parse and assert a non-empty first path segment before calling migrate.
Example fix
// before bitbucket://user:pass@myteam // after bitbucket://user:pass@myteam/myrepo/migrations#master
Defensive patterns
Strategy: validation
Validate before calling
u, _ := nurl.Parse(sourceURL)
pe := strings.Split(strings.Trim(u.Path, "/"), "/")
if u.Scheme == "bitbucket" && (u.Path == "" || pe[0] == "") {
return fmt.Errorf("bitbucket source URL needs /repo as first path segment")
} Type guard
func hasRepoSegment(u *nurl.URL) bool {
pe := strings.Split(strings.Trim(u.Path, "/"), "/")
return len(pe) >= 1 && pe[0] != ""
} Try / catch
d, err := bitbucket.Open(url)
if errors.Is(err, bitbucket.ErrInvalidRepo) {
return fmt.Errorf("invalid bitbucket source URL: use bitbucket://user:pass@owner/repo/path#ref")
} Prevention
- Remember the URL layout: host = owner, first path segment = repo.
- Validate the composed URL with url.Parse before use.
- Fail fast on empty repo placeholders in config templates.
- Document the source URL format for your team.
When it happens
Trigger: `bitbucket://user:pass@owner` or `bitbucket://user:pass@owner/` with an empty path — len(pe) < 1 after Trim/ Split. Note: a completely empty path also yields pe == [""] with len 1, so this fires only for pathless-but-nonempty split outcomes; a truly empty repo still results in downstream API errors, so always supply /repo.
Common situations: Copy-pasting a database-style URL and dropping the repo segment; template/config where the repo placeholder stayed empty; confusion between owner (host) and repo (first path segment) layout of the bitbucket URL scheme.
Related errors
AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02).
Data as JSON: /api/errors/474347f756651d80.
Report an issue: GitHub.