{"record":{"id":"f85a9fb52d66ec15","repo":"golang-migrate/migrate","slug":"no-username-token-provided","errorCode":null,"errorMessage":"no username:token provided","messagePattern":"no username:token provided","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"source/github/github.go","lineNumber":24,"sourceCode":"\t\"io\"\n\t\"net/http\"\n\tnurl \"net/url\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\n\t\"golang.org/x/oauth2\"\n\n\t\"github.com/golang-migrate/migrate/v4/source\"\n\t\"github.com/google/go-github/v39/github\"\n)\n\nfunc init() {\n\tsource.Register(\"github\", &Github{})\n}\n\nvar (\n\tErrNoUserInfo          = fmt.Errorf(\"no username:token provided\")\n\tErrNoAccessToken       = fmt.Errorf(\"no access token\")\n\tErrInvalidRepo         = fmt.Errorf(\"invalid repo\")\n\tErrInvalidGithubClient = fmt.Errorf(\"expected *github.Client\")\n\tErrNoDir               = fmt.Errorf(\"no directory\")\n)\n\ntype Github struct {\n\tconfig     *Config\n\tclient     *github.Client\n\toptions    *github.RepositoryContentGetOptions\n\tmigrations *source.Migrations\n}\n\ntype Config struct {\n\tOwner string\n\tRepo  string\n\tPath  string\n\tRef   string","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/source/github/github.go#L6-L42","documentation":"github.ErrNoUserInfo is returned by Github.Open when the URL contains userinfo (u.User != nil) but no password component, i.e. there is no colon-separated token. The GitHub driver uses the password part of the URL as the OAuth access token.","triggerScenarios":"Open('github://user@github.com/owner/repo') — username present, no ':token' — causes u.User.Password() to return ok=false and Open returns ErrNoUserInfo.","commonSituations":"Writing 'github://x@github.com/...' assuming any user works; templating that dropped the token after the colon; confusing this driver's 'username:token' format with token-only auth used elsewhere.","solutions":["Include the token as the password part: 'github://<anything>:<token>@github.com/owner/repo'","Or omit userinfo entirely and rely on an unauthenticated client (rate-limited, will fail for private repos)","Or use WithInstance with a pre-configured *github.Client instead of URL auth"],"exampleFix":"// before\nsource.Open(\"github://myuser@github.com/owner/repo/migrations\")\n// after\nsource.Open(\"github://myuser:ghp_xxx@github.com/owner/repo/migrations\")","handlingStrategy":"validation","validationCode":"u, err := url.Parse(sourceURL)\nif err != nil {\n    return err\n}\nif u.User != nil {\n    if _, ok := u.User.Password(); !ok {\n        return fmt.Errorf(\"github source url needs username:token, got user only\")\n    }\n}","typeGuard":"func hasGitHubToken(raw string) bool {\n    u, err := url.Parse(raw)\n    if err != nil || u.User == nil {\n        return false\n    }\n    pw, ok := u.User.Password()\n    return ok && pw != \"\"\n}","tryCatchPattern":"d, err := githubSource.Open(srcURL)\nif err != nil {\n    if errors.Is(err, source_github.ErrNoUserInfo) {\n        return fmt.Errorf(\"embed token as password in URL: user:token@github.com\")\n    }\n    return err\n}","preventionTips":["Format credentials as user:token, never user-only","Inject the token from env/secrets and assert non-empty before building the URL","Prefer WithInstance with a programmatically built *github.Client for complex auth"],"tags":["github","authentication","url"],"backgroundTag":"missing-credentials","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}