puppetlabs/puppet · error · Puppet::Error
Missing action
Error message
Missing action
What it means
Raised while parsing a symbolic mode clause: the comma-separated part did not match ^([ugoa]*)([-+=].*)$, so no who-plus-action pair exists. There is a who list (or bare permissions) but no operator to say what to do with them.
Source
Thrown at lib/puppet/util/symbolic_file_mode.rb:79
original_mode = {
's' => (to_mode & 0o7000) >> 9,
'u' => (to_mode & 0o0700) >> 6,
'g' => (to_mode & 0o0070) >> 3,
'o' => (to_mode & 0o0007) >> 0,
# Are there any execute bits set in the original mode?
'any x?' => (to_mode & 0o0111) != 0
}
final_mode = {
's' => original_mode['s'],
'u' => original_mode['u'],
'g' => original_mode['g'],
'o' => original_mode['o'],
}
modification.split(/\s*,\s*/).each do |part|
_, to, dsl = /^([ugoa]*)([-+=].*)$/.match(part).to_a
if dsl.nil? then raise Puppet::Error, _('Missing action') end
to = "a" unless to and to.length > 0
# We want a snapshot of the mode before we start messing with it to
# make actions like 'a-g' atomic. Various parts of the DSL refer to
# the original mode, the final mode, or the current snapshot of the
# mode, for added fun.
snapshot_mode = {}
final_mode.each { |k, v| snapshot_mode[k] = v }
to.gsub('a', 'ugo').split('').uniq.each do |who|
value = snapshot_mode[who]
action = '!'
actions = {
'!' => ->(_, _) { raise Puppet::Error, _('Missing operation (-, =, or +)') },
'=' => ->(m, v) { m | v },
'+' => ->(m, v) { m | v },View on GitHub (pinned to e227c27540)
Solutions
- Add the operator: 'u+rw', 'g=r-x', 'o-rwx'.
- Remove extra/trailing commas and check that every comma-separated clause has who+operator+permissions.
Example fix
# before
file { '/tmp/x': mode => 'rw' }
# after
file { '/tmp/x': mode => 'u+rw' } Defensive patterns
Strategy: validation
Validate before calling
mode.split(/\s*,\s*/).each do |clause|
raise ArgumentError, "clause #{clause.inspect} lacks an operator" unless clause =~ /^([ugoa]*)([-+=].*)$/
end
Puppet::Util::SymbolicMode.symbolic_mode_to_int(mode) Type guard
def valid_symbolic_mode?(m)
m.is_a?(String) && !m.empty? &&
m.split(/\s*,\s*/).all? { |c| c =~ /^([ugoa]*)([-+=].*)$/ }
end Prevention
- Model modes after chmod(1) examples: who+what.
- Validate mode strings in module specs.
- Avoid building modes by string concatenation.
When it happens
Trigger: symbolic_mode_to_int('rx'), mode => 'u', or any clause like 'ugo', 'rwx', or 'x' with no -, + or =; also fragments left behind by stray commas such as 'u+r,g'.
Common situations: Hand-written modes missing the operator ('rw' instead of 'u+rw'); trailing commas splitting the mode into an empty/bare fragment; concatenating variables into mode strings.
Related errors
- Missing operation (-, =, or +)
- Unknown operation
- One or more file(s) specified did not exist: %{files}
- An empty mode string is illegal
- Numeric modes must be in octal, not decimal!
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/2ab2965cb200c54e.
Report an issue: GitHub.