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 == ""
endView on GitHub (pinned to e227c27540)
Solutions
- Remove stage from the resource
- Put the resource in a class and stage the class: class { 'myapp::config': stage => pre }
- 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
- Use the stage metaparameter only on class declarations (class { 'x': stage => pre })
- Order plain resources with require/before, never with stage
- Add a puppet-lint/custom check rejecting stage on non-class resources
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
- Invalid value %{value}.
- Duplicate declaration: %{resource} is already declared; cann
- Function Load Error for function '%{function_name}': %{messa
- A required parameter cannot be added after an optional param
- block_param accepts max 2 arguments (type, name), got %{size
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/90d54fae33a59c43.
Report an issue: GitHub.