golang-migrate/migrate · error
invalid response
Error message
invalid response
What it means
ErrInvalidResponse is returned by the gitlab driver's readDirectory, ReadUp and ReadDown methods whenever the GitLab HTTP API responds with a status code other than 200 OK. It deliberately discards the underlying response status so callers see a single sentinel; the actual cause is almost always an authentication or permissions problem with the configured token.
Source
Thrown at source/gitlab/gitlab.go:28
"strconv"
"strings"
"github.com/golang-migrate/migrate/v4/source"
"github.com/xanzy/go-gitlab"
)
func init() {
source.Register("gitlab", &Gitlab{})
}
const DefaultMaxItemsPerPage = 100
var (
ErrNoUserInfo = fmt.Errorf("no username:token provided")
ErrNoAccessToken = fmt.Errorf("no access token")
ErrInvalidHost = fmt.Errorf("invalid host")
ErrInvalidProjectID = fmt.Errorf("invalid project id")
ErrInvalidResponse = fmt.Errorf("invalid response")
)
type Gitlab struct {
client *gitlab.Client
url string
projectID string
path string
listOptions *gitlab.ListTreeOptions
getOptions *gitlab.GetFileOptions
migrations *source.Migrations
}
type Config struct {
}
func (g *Gitlab) Open(url string) (source.Driver, error) {
u, err := nurl.Parse(url)View on GitHub (pinned to 01a9643f14)
Solutions
- Confirm the access token is valid and has 'api' and 'read_repository' scopes (test with curl -H "PRIVATE-TOKEN: ..." https://host/api/v4/projects)
- Check the project path/id and ref (branch) in the gitlab:// URL point to an existing repository
- Inspect GitLab server logs or retry manually to rule out a transient 5xx outage
- If you need the real status code, wrap the driver or check GitLab API access independently, since the sentinel hides the HTTP status
Example fix
// before
db.Open("gitlab://user:expired-token@gitlab.example.com/group/project")
// after — regenerate token with api scope
db.Open("gitlab://oauth2:glpat-newtoken@gitlab.example.com/group/project?x-migrations-table=..." ) Defensive patterns
Strategy: try-catch
Validate before calling
req, _ := http.NewRequest("GET", host+"/api/v4/projects/"+url.PathEscape(projectID), nil)
req.Header.Set("PRIVATE-TOKEN", token)
resp, err := http.DefaultClient.Do(req)
if err != nil || resp.StatusCode != http.StatusOK {
return fmt.Errorf("gitlab API preflight failed: status=%d err=%v", respStatus(resp), err)
} Try / catch
src, err := gitlabDriver.WithInstance(...)
if errors.Is(err, gitlab.ErrInvalidResponse) {
// token/permission/API problem; verify token manually and retry with backoff
return fmt.Errorf("gitlab rejected request (check token scope/permissions): %w", err)
} Prevention
- Check token validity and 'api'/'read_repository' scope before deploying
- Test the exact project path and branch against the GitLab API with curl
- Handle 5xx with retries; treat 401/403 as fatal config errors
- Rotate tokens before expiry and store them in a secret manager
When it happens
Trigger: ListTree/GetFile calls against the GitLab API returning 401/403/404/500 — e.g. readDirectory during Open/WithInstance, or ReadUp/ReadDown fetching migration content with a non-200 response.
Common situations: Expired or revoked personal access token, token lacking 'api'/'read_repository' scope, wrong project id or branch name, private project the token cannot see, or GitLab downtime returning 5xx.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02).
Data as JSON: /api/errors/4586c7713d0d8bae.
Report an issue: GitHub.