discourse/discourse · error · Discourse::InvalidParameters
traffic_type
Error message
traffic_type
What it means
For the traffic_type dimension, normalize_filter_value coerces the item to a string and requires it to be in the TRAFFIC_TYPE_VALUES allowlist; anything else raises Discourse::InvalidParameters.new(:traffic_type). The allowlist is the fixed set of traffic classification buckets the explorer can query.
Source
Thrown at app/services/admin_dashboard_site_traffic_explorer.rb:73
errors.add(:start_date, :invalid)
end
def normalize_filter(key, value)
return nil if value.nil?
raise Discourse::InvalidParameters.new(key) if value.empty? || value.size > DIMENSION_LIMIT
value.map { |item| normalize_filter_value(key, item) }.uniq
end
def normalize_filter_value(key, value)
return "" if key == :referrer && value == ""
raise Discourse::InvalidParameters.new(key) if value.blank?
case key
when :traffic_type
traffic_type = value.to_s
raise Discourse::InvalidParameters.new(key) if !TRAFFIC_TYPE_VALUES.include?(traffic_type)
traffic_type
when :top_url, :entry_url
BrowserPageviewEventUrlNormalizer.normalize_site_path(value) ||
raise(Discourse::InvalidParameters.new(key))
when :country
country = value.to_s.upcase
raise Discourse::InvalidParameters.new(key) if !country.match?(/\A[A-Z]{2}\z/)
country
when :network
match = value.to_s.match(/\AAS(\d+)\z/)
raise Discourse::InvalidParameters.new(key) if !match
match[1].to_i
when :browser
browser = value.to_s
raise Discourse::InvalidParameters.new(key) if !BROWSER_VALUES.include?(browser)
browser
when :ip
IPAddr.new(value.to_s).to_sView on GitHub (pinned to 1b2d7253e8)
Solutions
- Read TRAFFIC_TYPE_VALUES from the service class and drive the UI dropdown from it
- Send exactly the canonical strings (e.g. the values defined in AdminDashboardSiteTrafficExplorer::TRAFFIC_TYPE_VALUES)
- On error, fetch/refresh the allowlist rather than guessing
Example fix
# before
filters = {traffic_type: ["Organic"]}
# after
filters = {traffic_type: AdminDashboardSiteTrafficExplorer::TRAFFIC_TYPE_VALUES.first(1) Defensive patterns
Strategy: type-guard
Validate before calling
values &= AdminDashboardSiteTrafficExplorer::TRAFFIC_TYPE_VALUES
Type guard
def valid_traffic_type?(v) AdminDashboardSiteTrafficExplorer::TRAFFIC_TYPE_VALUES.include?(v.to_s) end
Try / catch
rescue Discourse::InvalidParameters => e
render json: { errors: ["traffic_type must be one of the allowed values"] }, status: 400
end Prevention
- Populate the dropdown from the constant
- Re-sync allowlists after upgrades
- Reject unknown labels early
When it happens
Trigger: ?traffic_type=organic or ?traffic_type=email when those are not in TRAFFIC_TYPE_VALUES; sending a symbol-like raw value, wrong casing, or a pluralized label from a custom UI.
Common situations: Custom dashboards or scripts invent traffic type labels instead of using the API's canonical values; Discourse version changes alter the allowlist set; copy-paste from docs of a different version.
Related errors
- Invalid parameters
- country
- Discourse::InvalidAccess
- Discourse::NotFound
- backup.backup_file_should_be_tar_gz
AI-assisted analysis of discourse/discourse@1b2d7253e8 (2026-08-26).
Data as JSON: /api/errors/196ce0f4598dd0e6.
Report an issue: GitHub.