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

  1. Read the embedded cause before ' in symbolic mode' — it names the real problem and the failing clause.
  2. Fix the flagged clause per its specific error: add the operator, remove 8/9 digits, keep X with '+', drop unknown letters.
  3. 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

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


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