Skip to content
Latchkey

GoReleaser Homebrew tap push failed (token) in CI

GoReleaser generates a Homebrew formula and pushes it to your tap repository. The built-in GITHUB_TOKEN only has access to the current repo, so pushing to a separate tap repo fails without a token scoped to it.

What this error means

The release builds and publishes, then fails at the brew step with "failed to push homebrew tap" or "403 Forbidden" writing to the tap repository.

Terminal
  ⨯ homebrew tap failed  error=failed to push homebrew tap:
  PUT https://api.github.com/repos/acme/homebrew-tap/contents/Formula/app.rb:
  403 Forbidden

Common causes

The default token cannot write the tap repo

The built-in GITHUB_TOKEN is scoped to the release repo only, so it cannot commit the formula to homebrew-tap.

The tap token is missing or misconfigured

The brews.repository.token env is not set to a PAT with write access to the tap repository.

How to fix it

Provide a PAT scoped to the tap repo

  1. Create a PAT with write access to the tap repository.
  2. Store it as a secret and reference it in the brews config token.
  3. Pass that secret in the GoReleaser step env.
.goreleaser.yaml
brews:
  - repository:
      owner: acme
      name: homebrew-tap
      token: "{{ .Env.TAP_GITHUB_TOKEN }}"

Expose the tap token in the workflow

Set the tap PAT alongside GITHUB_TOKEN in the step env so GoReleaser can push the formula.

.github/workflows/release.yml
env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  TAP_GITHUB_TOKEN: ${{ secrets.TAP_GITHUB_TOKEN }}

How to prevent it

  • Use a dedicated PAT with write access to external tap repos.
  • Keep the tap token in secrets and reference it via .Env.
  • Grant least-privilege access limited to the tap repository.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →