instructure/canvas-lms · error · ArgumentError

setting_name cannot be nil

Error message

setting_name cannot be nil

What it means

ArgumentError raised by the CanvasOperations::Settings#setting helper when the setting_name positional argument is nil. Setting names become part of the namespaced Setting key, so a nil name cannot be resolved.

Solutions

  1. Pass a non-nil Symbol or String as the first argument
  2. Guard the call site and provide a default name when the dynamic value is missing
  3. Fail fast upstream by validating the interpolated value before calling setting

Example fix

// before
setting(prefix && "#{prefix}_timeout".to_sym, default: 30)
// after
raise ArgumentError, 'prefix missing' unless prefix
setting("#{prefix}_timeout".to_sym, default: 30)
Defensive patterns

Strategy: type-guard

Validate before calling

raise 'setting name required' if name.nil?
raise 'must be Symbol or String' unless name.is_a?(Symbol) || name.is_a?(String)

Type guard

def valid_setting_name?(name)
  !name.nil? && (name.is_a?(Symbol) || name.is_a?(String))
end

Try / catch

rescue ArgumentError => e
  Rails.logger.error("Bad setting call: #{e.message}")
end

Prevention

When it happens

Trigger: Calling setting(nil, default: ...) on an operation class extending the Settings concern, typically because a computed name variable is nil.

Common situations: Building the setting name dynamically (e.g. "#{feature}_enabled".to_sym) where the interpolated variable is nil; refactors that changed a constant into a method returning nil.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/2ff16b1001450bf3. Report an issue: GitHub.

Appendix: source

Thrown at lib/canvas_operations/base_concerns/settings.rb:82

      def setting_for(name, default:, cluster:)
        Canvas::Reloader.reload

        settings_key = settings_key(name, cluster:)
        value = Setting.get(settings_key, default)
        log_message("Fetched setting #{settings_key} with value `#{value.inspect}` before type casting", level: :debug)

        value
      end

      def modify_setting_for(name, value, cluster:)
        was_success = Setting.set(settings_key(name, cluster:), value)
        log_message("Modified setting #{settings_key(name, cluster:)} to value `#{value.inspect}` successfully? #{was_success}")

        was_success
      end

      def setting(setting_name, default:, type_cast: :to_s)
        raise ArgumentError, "setting_name cannot be nil" if setting_name.nil?
        raise ArgumentError, "setting_name must be a symbol or string" unless setting_name.is_a?(Symbol) || setting_name.is_a?(String)

        validate_type_cast!(type_cast, setting_name)

        # Method to get the Setting value and apply type casting
        #
        # If no cluster is provided, the current shard's cluster.
        define_singleton_method(setting_name) do |cluster: nil|
          cluster ||= Shard.current.database_server.id

          raw_value = setting_for(setting_name, default:, cluster:)

          case type_cast
          when Symbol
            raw_value.public_send(type_cast)
          when Proc
            type_cast.call(raw_value)
          end

View on GitHub (pinned to 1c9f0bb801)