theonedev/onedev · error · ExplicitException

Unable to find version node

Error message

Unable to find version node

What it means

getGemVersion(MappingNode) parses a YAML node tagged !ruby/object:Gem::Version and expects a mapping key 'version'. If the mapping contains no such key, it throws ExplicitException("Unable to find version node"). This happens while OneDev deserializes gemspec dependency metadata embedded in the gem's metadata.gz during publish.

Source

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

		return new UserMarshal("Gem::Version", newArrayList(version));
	}
	
	private UserMarshal getGemRequirement(Map<String, UserMarshal> requiredVersions) {
		var requirements = new ArrayList<>();
		for (var entry: requiredVersions.entrySet()) 
			requirements.add(newArrayList(entry.getKey(), entry.getValue()));
		var value = new ArrayList<>();
		value.add(requirements);
		return new UserMarshal("Gem::Requirement", value);	
	}
	
	private UserMarshal getGemVersion(MappingNode node) {
		checkArgument(node.getTag().getValue().equals("!ruby/object:Gem::Version"));	
		for (var tuple: node.getValue()) {
			if (((ScalarNode)tuple.getKeyNode()).getValue().equals("version"))
				return getGemVersion(((ScalarNode)tuple.getValueNode()).getValue());
		}
		throw new ExplicitException("Unable to find version node");
	}
	
	private UserMarshal getGemRequirement(MappingNode node) {
		checkArgument(node.getTag().getValue().equals("!ruby/object:Gem::Requirement"));
		for (var tuple: node.getValue()) {
			if (((ScalarNode)tuple.getKeyNode()).getValue().equals("requirements")) {
				var requiredVersions = new LinkedHashMap<String, UserMarshal>();
				for (var requirementNode: ((SequenceNode)tuple.getValueNode()).getValue()) {
					var operatorAndVersion = ((SequenceNode)requirementNode).getValue();
					var operator = ((ScalarNode)operatorAndVersion.get(0)).getValue();
					var gemVersion = getGemVersion((MappingNode) operatorAndVersion.get(1));
					requiredVersions.put(operator, gemVersion);
				}
				return getGemRequirement(requiredVersions);
			}
		}
		throw new ExplicitException("Unable to find requirements node");
	}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Rebuild the gem with standard tooling: gem build mygem.gemspec, and re-push.
  2. Inspect metadata.gz (tar -xOf mygem-1.0.0.gem metadata.gz | gzip -d) to verify a 'version' key exists in the Gem::Version mapping.
  3. Update local RubyGems (gem update --system) if the gem was built with an unusual version.
  4. Avoid hand-editing gem internals.

Example fix

// before (hand-crafted YAML)
--- !ruby/object:Gem::Version
  raw_version: 1.0.0
// after
--- !ruby/object:Gem::Version
  version: 1.0.0
Defensive patterns

Strategy: validation

Validate before calling

# validate gem metadata before pushing
tar -xOf mygem-1.0.0.gem metadata.gz | gzip -d | grep -A1 'Gem::Version'
# ensure each Gem::Version mapping contains a 'version' key

Try / catch

begin
  gem_push('onedev-host', 'mygem-1.0.0.gem')
rescue => e
  raise unless e.message.include?('Unable to find version node')
  warn 'Malformed gem metadata: rebuild with `gem build`'
end

Prevention

When it happens

Trigger: Publishing a gem whose metadata.gz contains a Gem::Version mapping without a 'version' key — i.e. malformed or hand-edited gemspec YAML; also possible with gems produced by nonstandard tooling.

Common situations: Gems built/modified by custom scripts or old exotic RubyGems versions; corrupted upload where metadata.gz was truncated then re-zipped; gems crafted by tools other than gem build.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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