puppetlabs/puppet · error · Puppet::Error

Unknown operation

Error message

Unknown operation

What it means

Raised when a character in the permission part of a symbolic clause is outside the supported set: operators (-+=), who references (ugo), permission letters (rwx), X, and special bits (st). Anything else falls into the else branch and raises 'Unknown operation'.

Source

Thrown at lib/puppet/util/symbolic_file_mode.rb:132

          when 'X'
            # Only meaningful in combination with "set" actions.
            if action != '+'
              raise Puppet::Error, _("X only works with the '+' operator")
            end

            # As per the BSD manual page, set if this is a directory, or if
            # any execute bit is set on the original (unmodified) mode.
            # Ignored otherwise; it is "add if", not "add or clear".
            if is_a_directory or original_mode['any x?']
              value = actions[action].call(value, ExecBit)
            end

          when /[st]/
            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 |

View on GitHub (pinned to e227c27540)

Solutions

  1. Restrict each clause to [ugoa]*[-+=][ugo rwxXst]* syntax.
  2. Retype the mode instead of pasting; verify with a lint regex before deploying.

Example fix

# before
file { '/tmp/y': mode => 'a+read' }

# after
file { '/tmp/y': mode => 'a+r' }
Defensive patterns

Strategy: validation

Validate before calling

VALID_CLAUSE = /\A[ugoa]*[-+=+][ugo rwxXst]*\z/
raise ArgumentError, "invalid mode #{mode.inspect}" unless mode.split(/\s*,\s*/).all? { |c| c =~ VALID_CLAUSE }
Puppet::Util::SymbolicMode.symbolic_mode_to_int(mode)

Type guard

def symbolic_clause?(c)
  c =~ /\A[ugoa]*[-+=][ugo rwxXst]*\z/
end

Prevention

When it happens

Trigger: Typo or word characters: 'u+z', 'a+read', 'g=rw;q', or punctuation and backslashes pasted in from other tools.

Common situations: Writing words instead of single letters; copy-paste from docs with smart quotes or extra characters; programmatic mode building that includes separators.

Related errors


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