puppetlabs/puppet · error · ArgumentError

Only classes can set 'stage'; normal resources like %{resour

Error message

Only classes can set 'stage'; normal resources like %{resource} cannot change run stage

What it means

The compiler refuses the stage attribute on anything that is not a class (resource.class? is false). Run stages are a containment mechanism that only applies to classes; assigning a normal resource (file, service, or a resource from a define) to a stage raises ArgumentError.

Source

Thrown at lib/puppet/parser/compiler.rb:84

    resource = @catalog.resource(override.ref)
    if resource
      resource.merge(override)
    else
      # Otherwise, store the override for later; these
      # get evaluated in Resource#finish.
      @resource_overrides[override.ref] << override
    end
  end

  def add_resource(scope, resource)
    @resources << resource

    # Note that this will fail if the resource is not unique.
    @catalog.add_resource(resource)

    if !resource.class? and resource[:stage]
      # TRANSLATORS "stage" is a keyword in Puppet and should not be translated
      raise ArgumentError, _("Only classes can set 'stage'; normal resources like %{resource} cannot change run stage") % { resource: resource }
    end

    # Stages should not be inside of classes.  They are always a
    # top-level container, regardless of where they appear in the
    # manifest.
    return if resource.stage?

    # This adds a resource to the class it lexically appears in in the
    # manifest.
    unless resource.class?
      @catalog.add_edge(scope.resource, resource)
    end
  end

  # Store the fact that we've evaluated a class
  def add_class(name)
    @catalog.add_class(name) unless name == ""
  end

View on GitHub (pinned to e227c27540)

Solutions

  1. Remove stage from the resource
  2. Put the resource in a class and stage the class: class { 'myapp::config': stage => pre }
  3. Express ordering with require/before/notify/subscribe instead of stages

Example fix

// before
file { '/etc/app.conf': stage => pre, source => '...' }

// after
class myapp::config { file { '/etc/app.conf': source => '...' } }
class { 'myapp::config': stage => pre }
Defensive patterns

Strategy: validation

Validate before calling

# static pre-check over manifests: flag 'stage =>' on non-class resource declarations
grep -rn "stage\s*=>" manifests/ | grep -v "class {'"

Prevention

When it happens

Trigger: file { '/tmp/x': stage => pre }; any builtin/defined resource with a stage attribute; attempting to sequence plain resources via stages.

Common situations: Misunderstanding run stages and trying to use stage as a generic ordering metaparameter; migrating dependency chains; copy-paste from class examples onto resources.

Related errors


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