theonedev/onedev · error · ClientException

Invalid publish request body

Error message

Invalid publish request body

What it means

Thrown by CargoPackHandler.getIndexEntry when serializing a stored crate's index entry fails with an IOException. Despite the message, this happens while regenerating the sparse-index entry from stored publish metadata (readTree/writeValueAsBytes), typically because stored metadata JSON is unreadable/corrupt. It is surfaced to the client as an HTTP 400.

Source

Thrown at server-plugin/server-plugin-pack-cargo/src/main/java/io/onedev/server/plugin/pack/cargo/CargoPackHandler.java:286

			var publishMetadata = (ObjectNode) objectMapper.readTree(data.getMetadata());
			var indexEntry = objectMapper.createObjectNode();
			indexEntry.put("name", publishMetadata.path("name").asText());
			indexEntry.put("vers", publishMetadata.path("vers").asText());
			var depsNode = publishMetadata.path("deps");
			indexEntry.set("deps", depsNode instanceof ArrayNode ? toIndexDeps((ArrayNode) depsNode) : objectMapper.createArrayNode());
			indexEntry.put("cksum", data.getSha256BlobHash());
			indexEntry.set("features", publishMetadata.path("features"));
			indexEntry.put("yanked", data.isYanked());
			if (publishMetadata.hasNonNull("links"))
				indexEntry.set("links", publishMetadata.get("links"));
			if (publishMetadata.hasNonNull("rust_version"))
				indexEntry.set("rust_version", publishMetadata.get("rust_version"));
			indexEntry.put("v", 2);
			return objectMapper.writer()
					.without(SerializationFeature.INDENT_OUTPUT)
					.writeValueAsBytes(indexEntry);
		} catch (IOException e) {
			throw new ClientException(SC_BAD_REQUEST, "Invalid publish request body");
		}
	}

	private ArrayNode toIndexDeps(ArrayNode publishDeps) {
		var indexDeps = objectMapper.createArrayNode();
		for (var publishDep : publishDeps) {
			var dep = objectMapper.createObjectNode();
			var explicitName = publishDep.path("explicit_name_in_toml");
			dep.put("name", explicitName.isMissingNode() || explicitName.isNull()
					? publishDep.path("name").asText()
					: explicitName.asText());
			dep.put("req", publishDep.path("version_req").asText());
			dep.set("features", publishDep.path("features"));
			dep.put("optional", publishDep.path("optional").asBoolean(false));
			dep.put("default_features", publishDep.path("default_features").asBoolean(true));
			dep.set("target", publishDep.path("target"));
			dep.put("kind", publishDep.path("kind").asText("normal"));
			dep.set("registry", publishDep.path("registry"));

View on GitHub (pinned to d44925c47c)

Solutions

  1. Inspect CargoData.metadata for the affected pack and fix or re-publish the crate
  2. Re-publish the affected crate version to regenerate clean metadata
  3. Check server logs for the underlying IOException to identify the corrupt record
  4. Upgrade/verify the cargo pack plugin and Jackson versions are consistent
Defensive patterns

Strategy: try-catch

Validate before calling

// client-side: nothing to pre-validate; server-side validate stored metadata parses
JsonNode meta = objectMapper.readTree(data.getMetadata()); // throws -> corrupt record

Type guard

if (meta == null || !meta.isObject()) { /* corrupt metadata, republish */ }

Try / catch

try { entry = getIndexEntry(pack); } catch (ClientException e) { logger.error("corrupt metadata for pack", e); republish(pack); }

Prevention

When it happens

Trigger: A cargo client requests the sparse index (GET /index/... crate name) and the server cannot parse the stored metadata JSON of a published version into an ObjectNode, or Jackson fails to serialize the generated index entry.

Common situations: Corrupted CargoData.metadata stored during a faulty publish; manual DB edits to pack metadata; Jackson serialization feature conflicts after plugin upgrade.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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