{"record":{"id":"62d088611f125129","repo":"fluent/fluentd","slug":"empty-keys-in-dot-notation","errorCode":null,"errorMessage":"empty keys in dot notation","messagePattern":"empty keys in dot notation","errorType":"exception","errorClass":"Fluent::ConfigError","httpStatus":null,"severity":"error","filePath":"lib/fluent/plugin_helper/record_accessor.rb","lineNumber":113,"sourceCode":"          elsif param.start_with?('$[')\n            parse_bracket_notation(param)\n          else\n            param\n          end\n        end\n\n        def self.parse_dot_notation(param)\n          result = []\n          keys = param[2..-1].split('.')\n          keys.each { |key|\n            if key.include?('[')\n              result.concat(parse_dot_array_op(key, param))\n            else\n              result << key\n            end\n          }\n\n          raise Fluent::ConfigError, \"empty keys in dot notation\" if result.empty?\n          validate_dot_keys(result)\n\n          result\n        end\n\n        def self.validate_dot_keys(keys)\n          keys.each { |key|\n            next unless key.is_a?(String)\n            if /\\s+/.match?(key)\n              raise Fluent::ConfigError, \"whitespace character is not allowed in dot notation. Use bracket notation: #{key}\"\n            end\n          }\n        end\n\n        def self.parse_dot_array_op(key, param)\n          start = key.index('[')\n          result = if start.zero?\n                     []","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/fluent/fluentd/blob/dd45c6e18dc7be33b5e5a0f0767bf46307ff5626/lib/fluent/plugin_helper/record_accessor.rb#L95-L131","documentation":"Fluent::ConfigError from Fluent::RecordAccessor when parsing dot notation. An accessor path like $.a.b is split on '.' after stripping '$.'; at least one key (string or integer index) must remain. Paths where every segment is empty, such as '$.', '$..' or '$.[]', yield zero keys and are rejected at accessor-creation time.","triggerScenarios":"record_accessor_create(param) or Fluent::RecordAccessor::Accessor.new(param) with param equal to '$.', '$..' or '$.[]' - typically the result of concatenating a nil/empty value into a path string.","commonSituations":"Building accessor paths dynamically from record fields, env vars or user input where the key part is empty; trailing-dot typos in config values that expect record_accessor parameters.","solutions":["Fix the path to point at a real key: $.field or $.nested.field","Validate that the path has a non-empty key portion before creating the accessor","When keys come from external input, prefer bracket notation $['key'] which handles unusual key names"],"exampleFix":"# before\naccessor = record_accessor_create(param) # param == '$.' -> empty keys in dot notation\n\n# after\nraise ArgumentError, 'record path must name a key' if param.length <= 2\naccessor = record_accessor_create(param)","handlingStrategy":"validation","validationCode":"# cheap pre-check for an empty key portion\nraise ArgumentError, 'accessor path names no key' if param.length <= 2 || param == '$.[]'\naccessor = record_accessor_create(param)","typeGuard":null,"tryCatchPattern":"begin\n  accessor = Fluent::RecordAccessor::Accessor.new(param)\nrescue Fluent::ConfigError => e\n  log.warn \"bad record path #{param.inspect}: #{e.message}\"\n  accessor = nil\nend","preventionTips":["Never build dot paths by concatenating possibly-nil values","Unit-test accessor creation for every path your config/template can emit"],"tags":["fluentd","record-accessor","dot-notation","configuration"],"backgroundTag":"invalid-path-expression","analyzedSha":"dd45c6e18dc7be33b5e5a0f0767bf46307ff5626","analyzedAt":"2026-08-21T16:22:07.332Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}