opf/openproject · critical · ArgumentError

Value for #{name} must be one of #{allowed.join(', ')} but i

Error message

Value for #{name} must be one of #{allowed.join(', ')} but is #{value}

What it means

Setting definitions may declare an allowed list (Settings::Definition#valid_for?); for example log_level allows debug/info/warn/error/fatal and storage settings allow symbol sets like file/fog. When a value from configuration.yml or an OPENPROJECT_* environment override is applied via override_value, it is coerced and validated; a value outside the list raises ArgumentError naming the setting, the permitted values, and the value received. The raise happens while settings are resolved, i.e. at boot or on first access of that setting.

Source

Thrown at config/constants/settings/definition.rb:1564

    def persist_on_first_read?
      persist_on_first_read
    end

    def unprefixed_env_var_name_allowed?
      # Configuration values could be overridden with unprefixed env var
      # names before being harmonized (PR#10296). Using unprefixed en var
      # is deprecated and will be removed in 13.0.
      # Configuration are recognized by not being writable.
      !writable
    end

    def override_value(other_value)
      self.value = coerce(other_value)
      if valid_for?(value)
        self.writable = false
      else
        raise ArgumentError, "Value for #{name} must be one of #{allowed.join(', ')} but is #{value}"
      end
    end

    def valid_for?(value)
      return true if allowed.nil?

      # TODO: it would make sense to also check the type of the value (e.g. boolean).
      # But as using e.g. 0 for a boolean is quite common, that would break.
      if format == :array
        (value - allowed).empty?
      else
        allowed.include?(value)
      end
    end

    def allowed
      if @allowed.respond_to?(:call)
        @allowed.call

View on GitHub (pinned to d9742c43f3)

Solutions

  1. Read the message — it lists the setting name, every allowed value, and what you supplied; pick one of the allowed values
  2. Fix the offending entry in the environment (remember nested names use double underscores, e.g. OPENPROJECT_LOG__LEVEL) or in config/configuration.yml
  3. Remove the override entirely to fall back to the setting's default
  4. After upgrading OpenProject, diff config/constants/settings/definition.rb for the setting's allowed list — lists change between versions

Example fix

# before — boot fails with
#   ArgumentError: Value for log_level must be one of debug, info, warn, error, fatal but is verbose
environment:
  OPENPROJECT_LOG__LEVEL: "verbose"

# after
environment:
  OPENPROJECT_LOG__LEVEL: "debug"
Defensive patterns

Strategy: validation

Validate before calling

# deploy-time guard: check enumerated overrides against the same allowed lists
# the app uses (allowed values are printed in the error message and defined in
# config/constants/settings/definition.rb)
allowed = %w[debug info warn error fatal] # for log_level — take the list per setting
value = ENV.fetch("OPENPROJECT_LOG__LEVEL", nil)
if value && !allowed.include?(value)
  abort "OPENPROJECT_LOG__LEVEL must be one of #{allowed.join(', ')} (got #{value})"
end

Prevention

When it happens

Trigger: Setting an enumerated setting to a non-permitted value through its env var or configuration.yml, e.g. OPENPROJECT_LOG__LEVEL=verbose (allowed: debug, info, warn, error, fatal); array-format settings where any element is outside the allowed set ((value - allowed) not empty); range-allowed settings (e.g. allowed: 0..120, 1000..10_000) exceeded.

Common situations: Typos in env var values in docker-compose/Kubernetes manifests; configs copied between OpenProject versions where an allowed value was removed or renamed; numeric settings pushed past their configured range; values with the wrong case or whitespace so the include? check fails.

Related errors


AI-assisted analysis of opf/openproject@d9742c43f3 (2026-08-21). Data as JSON: /api/errors/0b1c333b2bb820ed. Report an issue: GitHub.