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

  1. Confirm the access token is valid and has 'api' and 'read_repository' scopes (test with curl -H "PRIVATE-TOKEN: ..." https://host/api/v4/projects)
  2. Check the project path/id and ref (branch) in the gitlab:// URL point to an existing repository
  3. Inspect GitLab server logs or retry manually to rule out a transient 5xx outage
  4. 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

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.