{"record":{"id":"f043c41789f9a7e2","repo":"puppetlabs/puppet","slug":"dependency-conflict-for-module-name-dependency","errorCode":null,"errorMessage":"Dependency conflict for %{module_name}: Dependency %{name} was given conflicting version requirements %{version_requirement} and %{dup_version}. Verify that there are no duplicates in the metadata.json.","messagePattern":"Dependency conflict for %(.+?): Dependency %(.+?) was given conflicting version requirements %(.+?) and %(.+?)\\. Verify that there are no duplicates in the metadata\\.json\\.","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/module_tool/metadata.rb","lineNumber":72,"sourceCode":"      process_name(data) if data['name']\n      process_version(data) if data['version']\n      process_source(data) if data['source']\n      process_data_provider(data) if data['data_provider']\n      merge_dependencies(data) if data['dependencies']\n\n      @data.merge!(data)\n      self\n    end\n\n    # Validates the name and version_requirement for a dependency, then creates\n    # the Dependency and adds it.\n    # Returns the Dependency that was added.\n    def add_dependency(name, version_requirement = nil, repository = nil)\n      validate_name(name)\n      validate_version_range(version_requirement) if version_requirement\n\n      dup = @data['dependencies'].find { |d| d.full_module_name == name && d.version_requirement != version_requirement }\n      raise ArgumentError, _(\"Dependency conflict for %{module_name}: Dependency %{name} was given conflicting version requirements %{version_requirement} and %{dup_version}. Verify that there are no duplicates in the metadata.json.\") % { module_name: full_module_name, name: name, version_requirement: version_requirement, dup_version: dup.version_requirement } if dup\n\n      dep = Dependency.new(name, version_requirement, repository)\n      @data['dependencies'].add(dep)\n\n      dep\n    end\n\n    # Provides an accessor for the now defunct 'description' property.  This\n    # addresses a regression in Puppet 3.6.x where previously valid templates\n    # referring to the 'description' property were broken.\n    # @deprecated\n    def description\n      @data['description']\n    end\n\n    def dependencies\n      @data['dependencies'].to_a\n    end","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/module_tool/metadata.rb#L54-L90","documentation":"Puppet::ModuleTool::Metadata#add_dependency raises ArgumentError when a dependency with the same full_module_name is already registered with a DIFFERENT version_requirement — i.e. metadata.json (or a merge into it) declares the same dependency twice with conflicting ranges. Identical duplicates are tolerated; conflicting ones are rejected to avoid an ambiguous requirement. merge_dependencies triggers this while parsing a metadata.json file.","triggerScenarios":"A metadata.json whose dependencies array lists puppetlabs-stdlib twice — once as '>= 4.0.0 < 6.0.0' and once as '>= 6.0.0' — parsed by Puppet::ModuleTool::Metadata (merge_dependencies → add_dependency); or programmatically calling metadata.add_dependency twice with different ranges.","commonSituations":"Hand-edited metadata.json where a dependency was appended instead of updated; ERB/templates concatenating dependency lists; merging module metadata from two sources; YAML-driven generators emitting one entry per template.","solutions":["Open metadata.json, grep for the duplicated name, and keep a single entry whose range covers what you need","Merge the two ranges into one constraint, e.g. '>= 4.0.0 < 7.0.0', instead of two entries","If generating metadata programmatically, check @data['dependencies'] for an existing entry and update it rather than adding again","Validate with `ruby -rjson -e \"puts JSON.parse(File.read('metadata.json'))['dependencies'].map { |d| d['name'] }.tally.select { |_,c| c>1 }\"` to find dupes"],"exampleFix":"// before - metadata.json\n\"dependencies\": [\n  { \"name\": \"puppetlabs/stdlib\", \"version_requirement\": \">= 4.0.0 < 6.0.0\" },\n  { \"name\": \"puppetlabs/stdlib\", \"version_requirement\": \">= 6.0.0\" }\n]\n\n// after\n\"dependencies\": [\n  { \"name\": \"puppetlabs/stdlib\", \"version_requirement\": \">= 4.0.0 < 8.0.0\" }\n]","handlingStrategy":"validation","validationCode":"deps = JSON.parse(File.read('metadata.json'))['dependencies']\ncounts = deps.map { |d| d['name'] }.group_by(&:itself).transform_values(&:length)\ndupes = counts.select { |_, c| c > 1 }\nabort \"duplicate dependencies: #{dupes.keys.join(', ')}\" unless dupes.empty?","typeGuard":null,"tryCatchPattern":"begin\n  metadata.add_dependency(dep_name, dep_range)\nrescue ArgumentError => e\n  raise if e.message !~ /conflicting version requirements/\n  # merge ranges instead of duplicating the entry\n  existing = metadata.dependencies.find { |d| d.full_module_name == dep_name }\n  merged = merge_ranges(existing.version_requirement, dep_range)\n  metadata.update('dependencies' => [{ 'name' => dep_name, 'version_requirement' => merged }])\nend","preventionTips":["Dedupe the dependencies array whenever you generate or hand-edit metadata.json","Keep one entry per dependency and encode all constraints in a single range","Run `puppet module build` as a smoke test after metadata edits — it parses and validates the file"],"tags":["puppet","module-tool","metadata","dependencies","duplicate","validation"],"backgroundTag":"duplicate-dependency-declaration","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}