Multi-package pixi publish aborts entire batch on first 409 (already-exists), instead of skipping that package
Checks
- I have checked that this issue has not already been reported.
- I have confirmed this bug exists on the latest version of pixi, using
pixi --version.
(Tested against pixi 0.79.0.)
Reproducible example
Commands I ran and their output:
$ pixi --version
pixi 0.79.0
$ pixi publish --target-channel quetz://<server>/<channel>
Publishing 86 workspace packages that set `publish = true`
Building 86 package(s):
- <pkg-a> v1.4.0 [<build>] (linux-64)
- <pkg-b> v1.0.0 [<build>] (linux-64)
... (84 more)
Publishing 86 package(s) to channel quetz://<server>/<channel>
INFO pixi_cli::publish: Uploading packages to Quetz: quetz://<server>/<channel>
INFO rattler_upload::upload: Uploading package file: <pkg-a>-1.4.0-<build>.conda (7.22 KiB)
Error: × Server responded with error
╰─▶ HTTP status client error (409 Conflict) for url (https://<server>/api/channels/<channel>/upload/<pkg-a>-1.4.0-<build>.conda?force=false&sha256=<hash>)
Already published at this version and build number (409 Conflict).All 86 packages built successfully first. The upload step then attempted exactly one file (<pkg-a>, unrelated to and unchanged from any of the other 85), got a 409 because that one artifact already exists at that version+build, and the entire publish aborted right there. None of the other 85 packages - including several that had genuinely new/changed content - were ever attempted.
pixi.toml file that reproduces my issue:
[workspace]
name = "example"
channels = ["conda-forge"]
platforms = ["linux-64"]
[feature.jazzy]
# ... publishes multiple pixi-build-ros member packages with publish = true(Any workspace publishing more than one package in a single pixi publish call, where at least one already exists unchanged on the target and at least one other has new content, reproduces this.)
pixi info output:
System
------------
Pixi version: 0.79.0
TLS backend: rustls
Platform: linux-64Other files: none needed beyond a multi-package workspace where one member's build already exists on the target channel.
Issue description
pixi publish --help documents:
Packages that already exist at the target are skipped by default. With this flag [
--no-skip-existing] they fail the publish instead...
This implies that when publishing a batch of packages, one already existing at the target should simply be skipped, and the rest of the batch should still be published. In practice, for a Quetz target, nothing is skipped client-side - the CLI just attempts the upload, gets a 409 from the server, and treats that as fatal for the entire remaining batch, even though only one package (out of many) actually conflicted.
Concretely, in crates/rattler_upload/src/upload/mod.rs, upload_package_to_quetz uploads package files one at a time in a loop and calls send_request_with_retry(...).await?; - the ? propagates the first non-2xx response (409 included) straight out of the function, aborting the loop and every package after it, rather than logging/skipping that one file and continuing.
This means in a workspace with many packages, a single stale/unrelated already-published artifact permanently blocks every future full-workspace publish, even for packages with genuinely new content, until that one artifact's version or build number is bumped (or the CLI's advertised default skip-existing behavior is actually implemented for Quetz).
Expected behavior
For a Quetz (and any other non-client-side-skip-checked) target, pixi publish of a multi-package batch should skip an individual package that already exists at the same version/build (409 response) and continue uploading the rest of the batch, matching the documented default ("skipped by default") - rather than aborting the whole publish on the first such conflict. --no-skip-existing should be the only way to make an existing-package conflict fatal, as the help text already implies.
Source: prefix-dev/pixi