{"record":{"id":"01906e1353413cf2","repo":"golang-migrate/migrate","slug":"no-password-app-password","errorCode":null,"errorMessage":"no password/app password","messagePattern":"no password/app password","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"source/bitbucket/bitbucket.go","lineNumber":22,"sourceCode":"\t\"fmt\"\n\t\"io\"\n\tnurl \"net/url\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/golang-migrate/migrate/v4/source\"\n\t\"github.com/ktrysmt/go-bitbucket\"\n)\n\nfunc init() {\n\tsource.Register(\"bitbucket\", &Bitbucket{})\n}\n\nvar (\n\tErrNoUserInfo             = fmt.Errorf(\"no username:password provided\")\n\tErrNoAccessToken          = fmt.Errorf(\"no password/app password\")\n\tErrInvalidRepo            = fmt.Errorf(\"invalid repo\")\n\tErrInvalidBitbucketClient = fmt.Errorf(\"expected *bitbucket.Client\")\n\tErrNoDir                  = fmt.Errorf(\"no directory\")\n)\n\ntype Bitbucket struct {\n\tconfig     *Config\n\tclient     *bitbucket.Client\n\tmigrations *source.Migrations\n}\n\ntype Config struct {\n\tOwner string\n\tRepo  string\n\tPath  string\n\tRef   string\n}\n","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/source/bitbucket/bitbucket.go#L4-L40","documentation":"ErrNoAccessToken is returned by the bitbucket driver's Open when the URL has a username but no password component (u.User.Password() returns ok=false). Bitbucket basic auth needs both username and password (an app password). Exported sentinel error.","triggerScenarios":"URLs like `bitbucket://user@owner/repo#ref` or `bitbucket://user:@owner/...` where the password is missing or empty; env var holding the app password is unset so the URL interpolates without the password.","commonSituations":"App password stored in env not exported in CI; colon omitted or password left blank in config; secret managers returning empty string; trailing whitespace trimmed away by URL parsing.","solutions":["Add the app password after the colon: `bitbucket://user:app-password@owner/repo/path#ref`.","Check the env/secret variable feeding the URL is set and non-empty in the environment running migrate.","Generate a Bitbucket app password with repository read scope if you don't have one.","Guard in code with errors.Is(err, bitbucket.ErrNoAccessToken) and surface a credential-missing message."],"exampleFix":"// before\nurl := fmt.Sprintf(\"bitbucket://%s@%s/%s\", user, owner, repo) // no password\n// after\nurl := fmt.Sprintf(\"bitbucket://%s:%s@%s/%s\", user, appPassword, owner, repo)","handlingStrategy":"validation","validationCode":"u, _ := nurl.Parse(sourceURL)\nif u != nil && u.User != nil {\n    if _, ok := u.User.Password(); !ok {\n        return fmt.Errorf(\"bitbucket URL has username %q but no password (app password)\", u.User.Username())\n    }\n}","typeGuard":"func hasURLPassword(u *nurl.URL) bool {\n    if u == nil || u.User == nil {\n        return false\n    }\n    p, ok := u.User.Password()\n    return ok && p != \"\"\n}","tryCatchPattern":"d, err := bitbucket.Open(url)\nif errors.Is(err, bitbucket.ErrNoAccessToken) {\n    return fmt.Errorf(\"missing app password in bitbucket source URL\")\n}","preventionTips":["Store the app password in env/secrets and assert it is non-empty before launching migrate.","Never leave the password slot empty after the colon in the URL.","Check CI env vars are exported to the migrate step.","Rotate app passwords via secrets manager, not inline config."],"tags":["bitbucket","authentication","app-password","config"],"backgroundTag":"missing-url-credentials","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}