goreleaser/goreleaser · error

incorrect response from opencollective: %s — %s

Error message

incorrect response from opencollective: %s — %s

What it means

GoReleaser's OpenCollective pipe posts a GraphQL mutation to the OpenCollective API. When the HTTP response status is anything other than 200 OK, it wraps the status line and the response body into this error via retryx.HTTP, meaning it is classified as a retriable HTTP failure and will be retried per the configured retry policy before finally failing the publish step.

Source

Thrown at internal/pipe/opencollective/opencollective.go:214

		if err != nil {
			return nil, retryx.Unrecoverable(fmt.Errorf("could not create request: %w", err))
		}
		req.Header.Set("Personal-Token", c.token)
		req.Header.Set("Content-Type", "application/json")

		resp, err := http.DefaultClient.Do(req)
		if err != nil {
			return nil, retryx.HTTP(fmt.Errorf("could not send request to opencollective: %w", err), resp)
		}
		defer resp.Body.Close()

		body, err := io.ReadAll(resp.Body)
		if err != nil {
			return nil, fmt.Errorf("could not read response from opencollective: %w", err)
		}

		if resp.StatusCode != http.StatusOK {
			return nil, retryx.HTTP(fmt.Errorf("incorrect response from opencollective: %s — %s", resp.Status, string(body)), resp)
		}

		return body, nil
	}, retryx.IsRetriable)
}

View on GitHub (pinned to f5edd73956)

Solutions

  1. Read the body after the em dash in the error message — it contains the exact OpenCollective API error (e.g. authentication required, unknown collective).
  2. Verify the Personal-Token is valid and not expired: curl -H 'Personal-Token: $TOKEN' https://api.opencollective.com/graphql/v2 with a {me { id }} query.
  3. Check that the configured open_collective project/collective slug in .goreleaser.yaml matches an existing collective.
  4. If it's a 429/5xx transient error, re-run the release or tune the retry configuration (ctx.Config.Retry).

Example fix

// before: failing config with bad token
# GORELEASER_OPENCOLLECTIVE_TOKEN=old-expired-token
// after: refresh token from https://opencollective.com/administrated-collectives
export GORELEASER_OPENCOLLECTIVE_TOKEN=<new-personal-token>
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight token check
token := os.Getenv("GORELEASER_OPENCOLLECTIVE_TOKEN")
if token == "" {
    return errors.New("GORELEASER_OPENCOLLECTIVE_TOKEN is not set")
}
req, _ := http.NewRequest("POST", "https://api.opencollective.com/graphql/v2",
    strings.NewReader(`{"query":"{ me { id } }"}`))
req.Header.Set("Personal-Token", token)
resp, err := http.DefaultClient.Do(req)
if err != nil || resp.StatusCode != http.StatusOK {
    return fmt.Errorf("opencollective token check failed: status %d", resp.StatusCode)
}

Try / catch

// the pipe already retries via retryx; wrap the run and inspect the status embedded in the message
if err := goreleaserRun(); err != nil {
    var httpErr interface{ StatusCode() int }
    if strings.Contains(err.Error(), "incorrect response from opencollective") {
        log.Printf("OpenCollective API rejected request (likely retriable): %v", err)
        // re-run after checking token validity
    }
}

Prevention

When it happens

Trigger: The doMutation call in internal/pipe/opencollective/opencollective.go:214 receives a non-200 status from the OpenCollective GraphQL endpoint — e.g. an invalid/expired Personal-Token (401/403), a malformed GraphQL mutation (400), rate limiting (429), or OpenCollective server errors (5xx). The raw API error body is embedded after the em dash.

Common situations: Expired or wrong opencollective personal token in the environment; the configured collective/project name does not exist so the GraphQL resolver errors; OpenCollective API outage or rate limit during a release; network proxy returning HTML error pages.

Related errors


AI-assisted analysis of goreleaser/goreleaser@f5edd73956 (2026-09-05). Data as JSON: /api/errors/30feb69932fc53ae. Report an issue: GitHub.