{"record":{"id":"b0bf194c54c78b52","repo":"golang-migrate/migrate","slug":"expected-github-client","errorCode":null,"errorMessage":"expected *github.Client","messagePattern":"expected \\*github\\.Client","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"source/github/github.go","lineNumber":27,"sourceCode":"\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\n}\n\nfunc (g *Github) Open(url string) (source.Driver, error) {","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/golang-migrate/migrate/blob/01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a/source/github/github.go#L9-L45","documentation":"github.ErrInvalidGithubClient is the sentinel returned when a value that is not a *github.Client is supplied where the driver requires one (e.g. constructing/validating the github source driver with an arbitrary client). It is a type assertion failure guard, not a network error.","triggerScenarios":"Passing a *http.Client, a wrapped client, or a differently-versioned go-github client type where *github.Client (go-github/v39) is expected; custom WithInstance wiring that asserts the wrong concrete type.","commonSituations":"Upgrading go-github major versions (v39 vs another) so the concrete type no longer matches; wrapping the client in middleware that changes its type.","solutions":["Pass a client created by github.NewClient(...) from the same go-github version the driver imports (v39)","If you wrapped the client, wrap inside via github.NewClient(baseHTTPClient) rather than substituting the type","Check import paths for version skew between your code and the migrate driver"],"exampleFix":"// before\nvar c any = myHTTPClient\nwithInstance(c) // not a *github.Client\n// after\nclient := github.NewClient(myHTTPClient)\nwithInstance(client) // *github.Client from go-github/v39","handlingStrategy":"type-guard","validationCode":"client, ok := c.(*github.Client)\nif !ok {\n    return fmt.Errorf(\"need *github.Client from go-github/v39, got %T\", c)\n}\nsource.WithInstance(client, cfg)","typeGuard":"func isGithubClient(v any) bool {\n    _, ok := v.(*github.Client)\n    return ok\n}","tryCatchPattern":"d, err := source_github.WithInstance(client, cfg)\nif err != nil {\n    if errors.Is(err, source_github.ErrInvalidGithubClient) {\n        return fmt.Errorf(\"wrong client type %T; use github.NewClient(...) (go-github/v39)\", client)\n    }\n    return err\n}","preventionTips":["Pin the same go-github major version as the migrate driver","Wrap HTTP transports, not the *github.Client itself","Let the compiler catch it: type parameters as *github.Client, not any"],"tags":["github","type-safety","client"],"backgroundTag":"wrong-client-type","analyzedSha":"01a9643f1475e75bb6d6224ddeaf9d8e2434ca8a","analyzedAt":"2026-09-02T19:38:29.671Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}