golang-migrate/migrate · error
no directory
Error message
no directory
What it means
github.ErrNoDir is returned by Github.readDirectory when the GitHub Contents API returns a single file instead of directory contents, meaning the configured path points at a file, not a directory of migrations.
Source
Thrown at source/github/github.go:28
"path"
"strings"
"golang.org/x/oauth2"
"github.com/golang-migrate/migrate/v4/source"
"github.com/google/go-github/v39/github"
)
func init() {
source.Register("github", &Github{})
}
var (
ErrNoUserInfo = fmt.Errorf("no username:token provided")
ErrNoAccessToken = fmt.Errorf("no access token")
ErrInvalidRepo = fmt.Errorf("invalid repo")
ErrInvalidGithubClient = fmt.Errorf("expected *github.Client")
ErrNoDir = fmt.Errorf("no directory")
)
type Github struct {
config *Config
client *github.Client
options *github.RepositoryContentGetOptions
migrations *source.Migrations
}
type Config struct {
Owner string
Repo string
Path string
Ref string
}
func (g *Github) Open(url string) (source.Driver, error) {
u, err := nurl.Parse(url)View on GitHub (pinned to 01a9643f14)
Solutions
- Point the path at the migrations directory, not an individual file (path without a filename)
- Verify the directory exists on the configured Ref (branch/tag/sha) via the GitHub UI or API
- If the repo keeps migrations at root or a subdir, adjust the URL path segment after owner/repo
Example fix
// before
source.Open("github://user:token@github.com/owner/repo/migrations/0001_init.up.sql")
// after
source.Open("github://user:token@github.com/owner/repo/migrations") Defensive patterns
Strategy: validation
Validate before calling
// before opening, confirm the path is a directory on the ref:
_, dir, _, err := client.Repositories.GetContents(ctx, owner, repo, path, &github.RepositoryContentGetOptions{Ref: ref})
if err != nil {
return err
}
if dir == nil {
return fmt.Errorf("%s on ref %s is a file, not a directory", path, ref)
} Type guard
func isDirectoryContent(fc *github.RepositoryContent, dir []*github.RepositoryContent) bool {
return fc == nil && len(dir) > 0
} Try / catch
d, err := source.Open(srcURL)
if err != nil {
if errors.Is(err, source_github.ErrNoDir) {
return fmt.Errorf("path in %q points to a file; use the migrations directory", srcURL)
}
return err
} Prevention
- Strip filenames from GitHub blob URLs; keep only the directory path
- Confirm the directory exists on the exact ref/branch configured
- Add a smoke check that lists the directory at startup
When it happens
Trigger: Configuring Path (or the URL path) to a single file such as .../migrations/0001_init.sql; the API returns fileContent != nil and readDirectory returns ErrNoDir.
Common situations: Typos in the migrations path; pointing at a symlink or a path that was moved; confusing file URL vs directory URL when copying from a GitHub blob URL.
Related errors
AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02).
Data as JSON: /api/errors/d83e698c1b034748.
Report an issue: GitHub.