{"record":{"id":"7cc16cd308613584","repo":"fluent/fluentd","slug":"array-required-but-got-val-inspect","errorCode":null,"errorMessage":"array required but got #{val.inspect}","messagePattern":"array required but got #(.+?)","errorType":"exception","errorClass":"ConfigError","httpStatus":null,"severity":"error","filePath":"lib/fluent/config/types.rb","lineNumber":244,"sourceCode":"\n    def self.array_value(val, opts = {}, name = nil)\n      return nil if val.nil?\n\n      param = if val.is_a?(String)\n                val.start_with?('[') ? JSON.parse(val, Fluent::DEFAULT_JSON_PARSE_OPTIONS) : val.strip.split(/\\s*,\\s*/)\n              elsif val.is_a?(Array)\n                val\n              elsif val.is_a?(Numeric) || val == true || val == false\n                # Wrap only the bare scalars that Psych/YAML actually produces\n                # here (nil is handled by the early return above). Any other\n                # type (Hash, Symbol, Time, arbitrary objects) falls through and\n                # still raises \"array required\" below.\n                [val]\n              else\n                val\n              end\n      if param.class != Array\n        raise ConfigError, \"array required but got #{val.inspect}\"\n      end\n      if opts[:value_type]\n        param.map{|v| REFORMAT_VALUE.call(opts[:value_type], v, opts, nil) }\n      else\n        param\n      end\n    end\n\n    ARRAY_TYPE = Proc.new { |val, opts = {}, name = nil|\n      Config.array_value(val, opts, name)\n    }\n  end\nend\n","sourceCodeStart":226,"sourceCodeEnd":258,"githubUrl":"https://github.com/fluent/fluentd/blob/dd45c6e18dc7be33b5e5a0f0767bf46307ff5626/lib/fluent/config/types.rb#L226-L258","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\n# config_param :fields, :array\nplugin.configure(config_element('match', '**', { fields: { \"a\" => 1 } }))\n\n# after\nplugin.configure(config_element('match', '**', { fields: \"a,b\" }))","handlingStrategy":"type-guard","validationCode":"def array_param_ok?(v)\n  v.is_a?(Array) || v.is_a?(String) || v.is_a?(Numeric) || v == true || v == false\nend","typeGuard":"def array_param_ok?(v)\n  v.is_a?(Array) || v.is_a?(String) || v.is_a?(Numeric) || v == true || v == false\nend","tryCatchPattern":"begin\n  Fluent::Config.array_value(val, opts, name)\nrescue Fluent::ConfigError => e\n  raise ConfigInvalid, \"#{name} must be an array or comma-separated string: #{e.message}\"\nend","preventionTips":["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(',')"],"tags":["fluentd","config","array","type-validation"],"backgroundTag":"config-type-mismatch","analyzedSha":"dd45c6e18dc7be33b5e5a0f0767bf46307ff5626","analyzedAt":"2026-08-21T16:22:07.332Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}