we-promise/sure · error · Provider::Trading212::ConfigurationError
Invalid environment: #{environment}
Error message
Invalid environment: #{environment} What it means
Provider::Trading212::ConfigurationError raised when the environment argument is not exactly "live" or "demo" (case-sensitive after to_s). The environment selects the base URI: live.trading212.com vs demo.trading212.com, so an unknown value has no endpoint to target.
Source
Thrown at app/models/provider/trading212.rb:42
RETRYABLE_ERRORS = [
SocketError,
Net::OpenTimeout,
Net::ReadTimeout,
Errno::ECONNRESET,
Errno::ECONNREFUSED,
Errno::ETIMEDOUT,
EOFError
].freeze
default_options.merge!({ timeout: 60 }.merge(httparty_ssl_options))
attr_reader :api_key, :api_secret, :environment
def initialize(api_key:, api_secret:, environment: "live")
raise ConfigurationError, "api_key is required" if api_key.blank?
raise ConfigurationError, "api_secret is required" if api_secret.blank?
raise ConfigurationError, "Invalid environment: #{environment}" unless %w[live demo].include?(environment.to_s)
@api_key = api_key.to_s.strip
@api_secret = api_secret.to_s.strip
@environment = environment.to_s
end
def fetch_account_summary
get("/equity/account/summary")
end
def fetch_positions
get("/equity/positions")
end
def fetch_instruments
get("/equity/metadata/instruments")
end
View on GitHub (pinned to e69894adb9)
Solutions
- Pass exactly "live" or "demo": Provider::Trading212.new(api_key:, api_secret:, environment: "demo")
- Whitelist and normalize in the caller before constructing: env = %w[live demo].include?(env.to_s.downcase) ? env.to_s.downcase : nil, and surface a validation message for anything else
- If the value comes from a form, store the machine value ("live"/"demo") not the display label
- Omit the argument entirely when you want the default "live" environment
Example fix
// before Provider::Trading212.new(api_key:, api_secret:, environment: params[:environment]) # "Live" -> raises // after env = params[:environment].to_s.downcase env = "live" unless %w[live demo].include?(env) Provider::Trading212.new(api_key:, api_secret:, environment: env)
Defensive patterns
Strategy: validation
Validate before calling
environment = params[:environment].to_s.downcase
unless %w[live demo].member?(environment)
raise ArgumentError, "environment must be 'live' or 'demo', got #{environment.inspect}"
end Try / catch
begin Provider::Trading212.new(api_key:, api_secret:, environment: env) rescue Provider::Trading212::ConfigurationError => e # treat as programmer/form error — do not retry, fix the input end
Prevention
- Use a form select with machine values live/demo, never free text
- Normalize case and whitespace before passing
- Add a unit test asserting both accepted values and rejection of 'production'/'staging'
When it happens
Trigger: Passing environment: "production", "Live" (capital L), "sandbox", "test", or a symbol like :live is fine (to_s) but :prod fails; passing nil (default "live" only applies when the arg is omitted, nil explicitly fails the include? check after to_s → "").
Common situations: UI dropdown saving a label like "Live account" instead of the value "live"; a config file renamed environments to production/staging; passing an unvalidated user-supplied string straight through.
Related errors
- api_key is required
- api_secret is required
- Trading 212 authentication failed (#{response.code}). Check
- Trading 212 rate limit exceeded. Please wait before retrying
- Trading 212 API key is missing.
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/99f4d72f66c15c21.
Report an issue: GitHub.