puppetlabs/puppet · error · ArgumentError

The code loaded from %{source_ref} does not define the resou

Error message

The code loaded from %{source_ref} does not define the resource type '%{type_name}' - got '%{got}'.

What it means

Raised after the instantiator evaluates the file (with the global scope as closure scope) and the evaluation result is not a Puppet::Pops::Resource::ResourceTypeImpl. The static checks passed, but the single statement evaluated to some other value; the message reports the actual class of the result. Note the code reads `resource_type.class` (the unevaluated model object), so the reported class reflects the parsed expression's class when the result is not the impl.

Source

Thrown at lib/puppet/pops/loader/puppet_resource_type_impl_instantiator.rb:63

        functor_expr.right_expr.is_a?(Model::QualifiedName) &&
        functor_expr.right_expr.value == 'new'
      else
        false
      end
    end
      raise ArgumentError, _("The code loaded from %{source_ref} does not create the resource type '%{type_name}' - no call to %{rname}.new found.") % { source_ref: source_ref, type_name: typed_name.name, rname: rname }
    end

    unless statements.size == 1
      raise ArgumentError, _("The code loaded from %{source_ref} must contain only the creation of resource type '%{type_name}' - it has additional logic.") % { source_ref: source_ref, type_name: typed_name.name }
    end

    closure_scope = Puppet.lookup(:global_scope) { {} }
    resource_type_impl = parser.evaluate(closure_scope, model)

    unless resource_type_impl.is_a?(Puppet::Pops::Resource::ResourceTypeImpl)
      got = resource_type.class
      raise ArgumentError, _("The code loaded from %{source_ref} does not define the resource type '%{type_name}' - got '%{got}'.") % { source_ref: source_ref, type_name: typed_name.name, got: got }
    end

    unless resource_type_impl.name == typed_name.name
      expected = typed_name.name
      actual = resource_type_impl.name
      raise ArgumentError, _("The code loaded from %{source_ref} produced resource type with the wrong name, expected '%{expected}', actual '%{actual}'") % { source_ref: source_ref, expected: expected, actual: actual }
    end

    # Adapt the resource type definition with loader - this is used from logic contained in it body to find the
    # loader to use when making calls to the new function API. Such logic have a hard time finding the closure (where
    # the loader is known - hence this mechanism
    Adapters::LoaderAdapter.adapt(resource_type_impl).loader_name = loader.loader_name
    resource_type_impl
  end
end
end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Make Resource::ResourceTypeImpl.new(...) a literal, plain call so evaluation returns the impl instance
  2. Inspect the 'got' class in the message to see what evaluation produced and adjust the file
  3. Verify against a known-good resource type file for your Puppet version
Defensive patterns

Strategy: try-catch

Type guard

def resource_type_impl?(obj)
  obj.is_a?(Puppet::Pops::Resource::ResourceTypeImpl)
end

Try / catch

begin
  impl = loader.load_typed(typed_name)
rescue ArgumentError => e
  raise unless e.message.include?("does not define the resource type")
  warn "evaluation did not yield a resource type: #{e.message}"
end

Prevention

When it happens

Trigger: `parser.evaluate(closure_scope, model)` returns a non-ResourceTypeImpl value while the earlier static shape checks passed -- e.g. the single statement builds the constructor dynamically or the evaluation yields nil/String.

Common situations: Edge cases where the parsed shape matched but evaluation diverges; exotic metaprogramming in a Puppet-language type file; Puppet version changes to the Resource API evaluation.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/b6c1495162749da4. Report an issue: GitHub.