goreleaser/goreleaser · error

ErrMultipleArchivesSamePlatform

ErrMultipleArchivesSamePlatform

Error message

one nixpkg can handle only one archive of each OS/Arch combination

What it means

The nix pipe builds one nixpkg derivation that must reference exactly one archive per OS/Arch combination. preparePkg collects archives into a map keyed by Goos+Goarch+Goarm; if a second archive maps to an existing key it returns ErrMultipleArchivesSamePlatform (internal/pipe/nix/nix.go:38, used at nix.go:344). This is a sentinel error so callers can check with errors.Is.

Source

Thrown at internal/pipe/nix/nix.go:38

	"github.com/caarlos0/log"
	"github.com/goreleaser/goreleaser/v2/internal/artifact"
	"github.com/goreleaser/goreleaser/v2/internal/client"
	"github.com/goreleaser/goreleaser/v2/internal/commitauthor"
	"github.com/goreleaser/goreleaser/v2/internal/experimental"
	"github.com/goreleaser/goreleaser/v2/internal/pipe"
	"github.com/goreleaser/goreleaser/v2/internal/skips"
	"github.com/goreleaser/goreleaser/v2/internal/summary"
	"github.com/goreleaser/goreleaser/v2/internal/tmpl"
	"github.com/goreleaser/goreleaser/v2/pkg/config"
	"github.com/goreleaser/goreleaser/v2/pkg/context"
)

const nixConfigExtra = "NixConfig"

// ErrMultipleArchivesSamePlatform happens when the config yields multiple
// archives for the same platform.
var ErrMultipleArchivesSamePlatform = errors.New("one nixpkg can handle only one archive of each OS/Arch combination")

type errNoArchivesFound struct {
	goamd64 string
	ids     []string
}

func (e errNoArchivesFound) Error() string {
	return fmt.Sprintf("no archives found matching goos=[darwin linux] goarch=[amd64 arm arm64 386] goarm=[6 7] goamd64=%s ids=%v", e.goamd64, e.ids)
}

var (
	errNoRepoName     = pipe.Skip("repository name is not set")
	errSkipUpload     = pipe.Skip("nix.skip_upload is set")
	errSkipUploadAuto = pipe.Skip("nix.skip_upload is set to 'auto', and current version is a pre-release")
	errInvalidLicense = errors.New("nix.license is invalid")
)

// New returns a pipe to be used in the publish phase.

View on GitHub (pinned to f5edd73956)

Solutions

  1. Set nix.ids to include only one build/archive per platform.
  2. Merge multiple binaries into a single build (use builds[].main/binary) instead of separate builds producing same-platform archives.
  3. Use nix.skip/archive-level filtering (e.g. internal binaries with build.skip) so duplicates for the same platform are excluded.

Example fix

// before
nix:
  ids: [app, app-extra] // both produce linux_amd64 archives
// after
nix:
  ids: [app]  // one archive per OS/Arch
Defensive patterns

Strategy: validation

Validate before calling

// assert at most one archive per platform among nix-included ids
nixIDs := map[string]bool{"app": true}
seen := map[string]bool{}
for _, a := range ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableArchive)).List() {
    if !nixIDs[a.ExtraOr("ID", "")] { continue }
    key := a.Goos + a.Goarch + a.Goarm
    if seen[key] { return fmt.Errorf("duplicate archive platform: %s", key) }
    seen[key] = true
}

Try / catch

if err := Pipe{}.Run(ctx); err != nil {
    if errors.Is(err, nix.ErrMultipleArchivesSamePlatform) {
        // drop second archive for same platform or split nix configs
    }
}

Prevention

When it happens

Trigger: Configuring nix for a build/archive setup that produces two archives for the same platform (e.g. two build ids both producing linux_amd64 archives included via nix.ids), such as a unibin-style config with duplicate archives per platform.

Common situations: Multiple builds without ids filtering on the nix pipe; archives produced both wrapped and unwrapped for the same platform; adding a second binary as a separate build instead of using builds' `binary` with a single build; the documented 'unibin' test case in nix_test.go:260.

Related errors


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