fluent/fluentd · error · ConfigError
array required but got #{val.inspect}
Error message
array required but got #{val.inspect} What it means
array_value accepts a comma-separated String (split into an Array of strings), an actual Array, and — as a documented convenience — wraps bare Numeric/true/false values produced by Psych/YAML; every other type falls through unchanged and fails the param.class != Array check, raising ConfigError. So Hashes, Symbols, Time objects, and arbitrary objects cannot be coerced into array params. The error is the guard against plugin defaults or programmatic config supplying the wrong shape.
Source
Thrown at lib/fluent/config/types.rb:244
def self.array_value(val, opts = {}, name = nil)
return nil if val.nil?
param = if val.is_a?(String)
val.start_with?('[') ? JSON.parse(val, Fluent::DEFAULT_JSON_PARSE_OPTIONS) : val.strip.split(/\s*,\s*/)
elsif val.is_a?(Array)
val
elsif val.is_a?(Numeric) || val == true || val == false
# Wrap only the bare scalars that Psych/YAML actually produces
# here (nil is handled by the early return above). Any other
# type (Hash, Symbol, Time, arbitrary objects) falls through and
# still raises "array required" below.
[val]
else
val
end
if param.class != Array
raise ConfigError, "array required but got #{val.inspect}"
end
if opts[:value_type]
param.map{|v| REFORMAT_VALUE.call(opts[:value_type], v, opts, nil) }
else
param
end
end
ARRAY_TYPE = Proc.new { |val, opts = {}, name = nil|
Config.array_value(val, opts, name)
}
end
end
View on GitHub (pinned to dd45c6e18d)
Solutions
- Pass an Array or a comma-separated string ('a,b,c')
- For programmatic values, map to strings and join: [:a, :b].map(&:to_s).join(',')
- Fix plugin defaults so :array params default to [] and never to a Hash
- If a mapping is genuinely needed, change the param declaration to :hash
Example fix
# before
# config_param :fields, :array
plugin.configure(config_element('match', '**', { fields: { "a" => 1 } }))
# after
plugin.configure(config_element('match', '**', { fields: "a,b" })) Defensive patterns
Strategy: type-guard
Validate before calling
def array_param_ok?(v) v.is_a?(Array) || v.is_a?(String) || v.is_a?(Numeric) || v == true || v == false end
Type guard
def array_param_ok?(v) v.is_a?(Array) || v.is_a?(String) || v.is_a?(Numeric) || v == true || v == false end
Try / catch
begin
Fluent::Config.array_value(val, opts, name)
rescue Fluent::ConfigError => e
raise ConfigInvalid, "#{name} must be an array or comma-separated string: #{e.message}"
end Prevention
- Pass Arrays or comma-separated strings; never Hashes or Symbols
- Keep plugin :array defaults as [] and review param type changes
- Convert symbols programmatically: %i[a b].join(',')
When it happens
Trigger: A plugin default declared as a Hash for an :array param; programmatic/test configuration passing symbols ([:debug, :info]) or a Hash to a :array param; YAML/JSON-loaded config feeding a Struct/Time into the param.
Common situations: Writing plugin tests with Ruby objects instead of config strings; copy-pasting a hash literal where a list was intended; plugin author changing a param type without updating the default.
Related errors
- hash required but got #{val.inspect}
- Unknown #{@kind} plugin '#{type}'. Run 'gem search -rd fluen
- Missing '@type' parameter on <#{e.name}> directive
- 'format' parameter is required
- both of utc and localtime are specified, use only one of the
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/7cc16cd308613584.
Report an issue: GitHub.