puppetlabs/puppet · error · Puppet::Error
%{error}%{rest} in symbolic mode %{modification}
Error message
%{error}%{rest} in symbolic mode %{modification} What it means
This is the wrapper message, not a distinct failure: any Puppet::Error raised while parsing a symbolic mode is re-raised with the offending clause and the whole mode attached ("<cause> at \"clause\" in symbolic mode \"...\""), preserving the original backtrace. Seeing it means one of the specific parse errors (empty mode, decimal digits, missing action, missing operation, X misuse, unknown operation) fired underneath.
Source
Thrown at lib/puppet/util/symbolic_file_mode.rb:146
bit = SymbolicSpecialToBit[op][who] or fail _("internal error")
final_mode['s'] = actions[action].call(final_mode['s'], bit)
else
raise Puppet::Error, _('Unknown operation')
end
end
# Now, assign back the value.
final_mode[who] = value
end
rescue Puppet::Error => e
if part.inspect != modification.inspect
rest = " at #{part.inspect}"
else
rest = ''
end
raise Puppet::Error, _("%{error}%{rest} in symbolic mode %{modification}") % { error: e, rest: rest, modification: modification.inspect }, e.backtrace
end
final_mode['s'] << 9 |
final_mode['u'] << 6 |
final_mode['g'] << 3 |
final_mode['o'] << 0
end
end
end
end
View on GitHub (pinned to e227c27540)
Solutions
- Read the embedded cause before ' in symbolic mode' — it names the real problem and the failing clause.
- Fix the flagged clause per its specific error: add the operator, remove 8/9 digits, keep X with '+', drop unknown letters.
- Temporarily replace the whole mode with a known-good octal value ('0644') to confirm the resource works, then rebuild the symbolic mode.
Example fix
# before: agent reports ... Missing action at "g" in symbolic mode "u+r,g"
file { '/tmp/z': mode => 'u+r,g' }
# after
file { '/tmp/z': mode => 'u+r,g+r' } Defensive patterns
Strategy: try-catch
Validate before calling
def valid_symbolic_mode?(m)
return false unless m.is_a?(String) && !m.empty?
m.split(/\s*,\s*/).all? do |c|
c =~ /\A[ugoa]*([-+=][ugo rwxXst]*)\z/ && !(c.include?('X') && c[/^([ugoa]*)([-+=])/, 2] != '+')
end
end Try / catch
begin
int_mode = Puppet::Util::SymbolicMode.symbolic_mode_to_int(mode, File.stat(file).mode)
rescue Puppet::Error => e
raise Puppet::Error, "invalid mode #{mode.inspect} for #{file}: #{e.message}"
end Prevention
- Parse the ' at <clause>' segment to locate the bad part quickly.
- Keep modes static strings, not interpolation targets.
- Cover every shipped mode with a spec example.
When it happens
Trigger: Any invalid symbolic mode reaching symbolic_mode_to_int; e.g. mode => 'u+r,g' produces 'Missing action at "g" in symbolic mode "u+r,g". It is the user-facing form logged by the agent for every symbolic-mode typo.
Common situations: Variable-interpolated modes that go wrong at runtime; refactoring modes across modules; the message users actually grep for in agent logs.
Related errors
- Missing action
- Missing operation (-, =, or +)
- X only works with the '+' operator
- Unknown operation
- File modes must be numbers
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/1cf01d9e6beabc49.
Report an issue: GitHub.