puppetlabs/puppet · error · Puppet::Error

Invalid environment mode '%{mode_name}'

Error message

Invalid environment mode '%{mode_name}'

What it means

Puppet::Application#environment_mode is a validating setter: it accepts only :local, :remote, or :not_required and raises Puppet::Error at call time for anything else. :local (the default when never called) requires the environment to exist on the local filesystem; :remote and :not_required are for agents and apps that do not need a local environment.

Source

Thrown at lib/puppet/application.rb:307

      require_relative '../puppet/util/run_mode'
      @run_mode = Puppet::Util::RunMode[mode_name || Puppet.settings.preferred_run_mode]
    end

    # Sets environment_mode name. When acting as a compiler, the environment mode
    # should be `:local` since the directory must exist to compile the catalog.
    # When acting as an agent, the environment mode should be `:remote` since
    # the Puppet[:environment] setting refers to an environment directoy on a remote
    # system. The `:not_required` mode is for cases where the application does not
    # need an environment to run.
    #
    # @param mode_name [Symbol] The name of the environment mode to run in. May
    #   be one of `:local`, `:remote`, or `:not_required`. This impacts where the
    #   application looks for its specified environment. If `:not_required` or
    #   `:remote` are set, the application will not fail if the environment does
    #   not exist on the local filesystem.
    # @api public
    def environment_mode(mode_name)
      raise Puppet::Error, _("Invalid environment mode '%{mode_name}'") % { mode_name: mode_name } unless [:local, :remote, :not_required].include?(mode_name)

      @environment_mode = mode_name
    end

    # Gets environment_mode name. If none is set with `environment_mode=`,
    # default to :local.
    # @return [Symbol] The current environment mode
    # @api public
    def get_environment_mode
      @environment_mode || :local
    end

    # This is for testing only
    # @api public
    def clear_everything_for_tests
      @run_mode = @banner = @run_status = @option_parser_commands = nil
    end
  end

View on GitHub (pinned to e227c27540)

Solutions

  1. Pass one of :local, :remote, :not_required as a symbol
  2. If no special mode is needed, simply do not call environment_mode — it defaults to :local
  3. Coerce config-driven strings with .to_sym and validate membership before calling

Example fix

# before
environment_mode(:none)

# after
environment_mode(:not_required)
Defensive patterns

Strategy: type-guard

Type guard

VALID_ENV_MODES = [:local, :remote, :not_required].freeze
def environment_mode!(mode)
  raise ArgumentError, "bad mode #{mode}" unless VALID_ENV_MODES.include?(mode)
  app.environment_mode(mode)
end

Prevention

When it happens

Trigger: An application subclass calling environment_mode with an unsupported value — environment_mode(:none), a string 'local' instead of the symbol, or a typo'd constant that evaluates to nil.

Common situations: Custom puppet applications copied from old examples using different mode names; refactors changing the argument; configuration-driven strings passed straight through without to_sym.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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