theonedev/onedev · error · ClientException

Package already exists (name: %s, version: %s)

Error message

Package already exists (name: %s, version: %s)

What it means

Before writing the gem blob, the handler checks the project's existing sha256 blob hashes for a file named <name>-<version>[-<platform>].gem. If it is already present, a 409 ClientException is thrown because gems are immutable in the registry — the same name/version combination cannot be published twice.

Source

Thrown at server-plugin/server-plugin-pack-gem/src/main/java/io/onedev/server/plugin/pack/gem/GemPackHandler.java:232

						data = (GemData) pack.getData();
					}

					Build build = null;
					if (buildId != null)
						build = buildService.load(buildId);
					pack.setBuild(build);
					pack.setUser(SecurityUtils.getUser());
					pack.setPublishDate(new Date());

					String fileName;
					if (StringUtils.isBlank(finalPlatform) || finalPlatform.equals("ruby"))
						fileName = String.format("%s-%s.gem", finalName, finalVersion).toLowerCase();
					else
						fileName = String.format("%s-%s-%s.gem", finalName, finalVersion, finalPlatform).toLowerCase();

					if (data.getSha256BlobHashes().containsKey(fileName)) {
						var errorMessage = String.format("Package already exists (name: %s, version: %s)", finalName, finalVersion);
						throw new ClientException(SC_CONFLICT, errorMessage);
					}
					data.getSha256BlobHashes().put(fileName, packBlob.getSha256Hash());

					var packBlobs = data.getSha256BlobHashes().values().stream()
							.map(hash -> packBlobService.findBySha256Hash(projectId, hash))
							.filter(Objects::nonNull)
							.collect(toList());
					packService.createOrUpdate(pack, packBlobs, data.getSha256BlobHashes().size() == 1);
					response.setStatus(SC_OK);
				}));
			} finally {
				FileUtils.deleteFile(tempFile);
			}
		} else if (pathSegments.equals(newArrayList("api", "v1", "gems", "yank"))) {
			if (!isDelete)
				throw new ClientException(SC_METHOD_NOT_ALLOWED);
			String name;
			String version;

View on GitHub (pinned to d44925c47c)

Solutions

  1. Bump the version in the gemspec (semantic versioning) and rebuild, then publish.
  2. Delete the existing package version in the project's package management UI if replacement is truly intended, then republish.
  3. Skip the publish step when the version already exists (e.g. CI idempotency check).

Example fix

# before
s.version = '1.0.0'
# after
s.version = '1.0.1'
Defensive patterns

Strategy: try-catch

Validate before calling

# check if the version already exists before publishing
curl -fsS -u user:token "https://onedev.example.com/~api/pack/gem/<project>" | grep -q "\"name\":\"mygem\",\"version\":\"1.0.0\"" && { echo 'already published'; exit 0; }

Try / catch

try { upload(gemFile) } catch (e) { if (e.httpStatus === 409 && /Package already exists/.test(e.message)) { log.info('version already published, skipping'); } else { throw e; } }

Prevention

When it happens

Trigger: Re-publishing a gem with the same name and version that already exists in the project (409 SC_CONFLICT).

Common situations: Re-running a CI publish job without version bump; re-deploying an old branch that still builds the same version; gemspec forgot a version increment after code changes.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/0a676709b75207dc. Report an issue: GitHub.