{"record":{"id":"ca05b260ed2a1c86","repo":"puppetlabs/puppet","slug":"cannot-alias-resource-to-key-at-resource-d","errorCode":null,"errorMessage":"Cannot alias %{resource} to %{key} at %{resource_declaration}; resource %{newref} already declared","messagePattern":"Cannot alias %(.+?) to %(.+?) at %(.+?); resource %(.+?) already declared","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/resource/catalog.rb","lineNumber":215,"sourceCode":"    # because sometimes an alias is created before the resource is\n    # added to the catalog, so comparing inside the below if block\n    # isn't sufficient.\n    existing = @resource_table[newref]\n    if existing\n      return if existing == resource\n\n      resource_declaration = Puppet::Util::Errors.error_location(resource.file, resource.line)\n      msg = if resource_declaration.empty?\n              # TRANSLATORS 'alias' should not be translated\n              _(\"Cannot alias %{resource} to %{key}; resource %{newref} already declared\") %\n                { resource: ref, key: key.inspect, newref: newref.inspect }\n            else\n              # TRANSLATORS 'alias' should not be translated\n              _(\"Cannot alias %{resource} to %{key} at %{resource_declaration}; resource %{newref} already declared\") %\n                { resource: ref, key: key.inspect, resource_declaration: resource_declaration, newref: newref.inspect }\n            end\n      msg += Puppet::Util::Errors.error_location_with_space(existing.file, existing.line)\n      raise ArgumentError, msg\n    end\n    @resource_table[newref] = resource\n    @aliases[ref] ||= []\n    @aliases[ref] << newref\n  end\n\n  # Apply our catalog to the local host.\n  # @param options [Hash{Symbol => Object}] a hash of options\n  # @option options [Puppet::Transaction::Report] :report\n  #   The report object to log this transaction to. This is optional,\n  #   and the resulting transaction will create a report if not\n  #   supplied.\n  #\n  # @return [Puppet::Transaction] the transaction created for this\n  #   application\n  #\n  # @api public\n  def apply(options = {})","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/resource/catalog.rb#L197-L233","documentation":"Raised by Puppet::Resource::Catalog#alias (lib/puppet/resource/catalog.rb:215) when a computed resource reference (Type[key], built from the resource class plus the alias key or namevar) is already present in the catalog's resource table and points to a different resource object. Aliases are normally created implicitly from a resource's namevar (e.g. a file's path) or explicitly via the `alias` metaparameter, so this is Puppet's duplicate-declaration guard. The message reports the declaration site of both the offending and the pre-existing resource.","triggerScenarios":"Declaring two resources of the same type whose title or namevar resolve to the same reference, e.g. file {'/etc/app.conf': ...} plus file {'app-conf': path => '/etc/app.conf'}; using the `alias` metaparameter with a key equal to another resource's title; calling catalog.alias(resource, key) or catalog.add_resource when @resource_table[[type, key]] already holds a different resource (the method returns silently only when existing == resource or when ref_string == ref).","commonSituations":"Two modules in the same role/profile both manage the same file, user, or package with different titles; a refactor renames a title while another declaration still uses the old name as an alias; overlapping profiles included on one node; a resource whose namevar (path, command, name) accidentally equals another resource's title.","solutions":["Read the message: it names both declarations via Puppet::Util::Errors.error_location — open each file:line and decide which declaration should win.","If both declarations are meant to be the same resource, delete one or replace it with stdlib's ensure_resource()/ensure_packages() so the second declaration is a no-op.","If titles must differ, give the resource its canonical namevar as title (e.g. file {'/etc/app.conf': ...}) and remove conflicting `alias` metaparameters.","If two distinct resources are intended, change the title or namevar so they no longer produce the same Type[key] reference (different path, different defined-type title)."],"exampleFix":"# before\nfile { '/etc/nginx/nginx.conf':\n  ensure => present,\n}\nfile { 'nginx-main-conf':\n  path   => '/etc/nginx/nginx.conf',  # namevar alias collides with File[/etc/nginx/nginx.conf]\n  ensure => present,\n}\n\n# after\nfile { '/etc/nginx/nginx.conf':\n  ensure => present,\n}\n# or make the second declaration idempotent:\n# ensure_resource('file', '/etc/nginx/nginx.conf', { 'ensure' => 'present' })","handlingStrategy":"validation","validationCode":"# before adding or aliasing a resource, confirm the reference is free\nref_string = \"#{resource.type}[#{key}]\"\nexisting = catalog.resource(ref_string)\nif existing && existing != resource\n  raise ArgumentError, \"#{ref_string} already declared at #{existing.file}:#{existing.line}\"\nend\ncatalog.alias(resource, key)","typeGuard":null,"tryCatchPattern":"begin\n  catalog.alias(resource, key)\nrescue ArgumentError => e\n  raise unless e.message.include?('already declared')\n  Puppet.warning(\"skipping duplicate #{resource.ref}: #{e.message}\")\nend","preventionTips":["Give resources their canonical namevar as title (file path, package name) so identity is unambiguous","Use stdlib ensure_resource/ensure_packages for resources declared from multiple modules","Compile catalogs in CI (puppet parser validate / catalog tests) to catch duplicates before agent runs","Avoid the `alias` metaparameter unless uniqueness of the target ref is guaranteed"],"tags":["puppet","catalog","duplicate-resource","alias","argumenterror"],"backgroundTag":"duplicate-resource-declaration","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}