puppetlabs/puppet · error · ArgumentError
Could not parse '%{string}'
Error message
Could not parse '%{string}' What it means
Each comma-separated entry inside a {...} file-options block must match /^\s*(\w+)\s*=\s*(\w+)\s*$/ — one word, an equals sign, one word. Anything else (empty value `mode =`, values containing dashes/slashes/dots/plus like group = puppet+shadow, trailing commas producing empty strings, stray text) raises ArgumentError 'Could not parse ...' with the whole original setting string for context.
Source
Thrown at lib/puppet/settings/config_file.rb:140
def extract_fileinfo(string)
result = {}
value = string.sub(/\{\s*([^}]+)\s*\}/) do
params = ::Regexp.last_match(1)
params.split(/\s*,\s*/).each do |str|
if str =~ /^\s*(\w+)\s*=\s*(\w+)\s*$/
param = ::Regexp.last_match(1).intern
value = ::Regexp.last_match(2)
result[param] = value
unless [:owner, :mode, :group].include?(param)
raise ArgumentError, _("Invalid file option '%{parameter}'") % { parameter: param }
end
if param == :mode and value !~ /^\d+$/
raise ArgumentError, _("File modes must be numbers")
end
else
raise ArgumentError, _("Could not parse '%{string}'") % { string: string }
end
end
''
end
result[:value] = value.sub(/\s*$/, '')
result
end
end
View on GitHub (pinned to e227c27540)
Solutions
- Keep every pair strictly as name = value with single-word values (letters, digits, underscore only).
- Remove trailing/leading commas and never leave an empty value; drop the pair entirely if unset.
- For values with punctuation (domain groups), precompute a plain name Puppet's regex accepts or manage ownership via a file resource instead.
Example fix
# before
vardir = /opt/puppet { owner = puppet, mode = 750, }
# after
vardir = /opt/puppet { owner = puppet, mode = 750 } Defensive patterns
Strategy: validation
Validate before calling
block.split(/\s*,\s*/).each do |pair|
raise ArgumentError, "unparseable file option pair: #{pair.inspect}" unless pair.match?(/^\s*(\w+)\s*=\s*(\w+)\s*$/)
end Try / catch
begin
Puppet::Settings::ConfigFile.parse_file(file, text, [])
rescue ArgumentError => e
raise unless e.message.include?("Could not parse")
Puppet.err("each {...} entry must be name = value with single-word values: #{e.message}")
raise
end Prevention
- Keep {...} entries strictly word = word; no paths, dashes, pluses, or dots in values
- Never leave trailing commas or empty values inside the braces
- For names with punctuation (domain groups), manage ownership via a file resource instead
When it happens
Trigger: `logdir = /var/log/puppet { owner = puppet, }` (trailing comma -> empty pair); `{ mode = 750, group = domain\\users }` (backslashes not word chars); `{ owner = }` empty value; multi-word junk inside the braces.
Common situations: Hand-editing file-option blocks; templating that leaves blank values for optional pairs; AD/domain group names or paths pasted into group/owner options; comment text accidentally left inside braces.
Related errors
- Invalid file option '%{parameter}'
- File modes must be numbers
- Parsing of 'type "%{assignment_string}"' failed with message
- The parameter '$#{name}' is invalid: #{e.message}
- Global option %{option} does not exist in Puppet.settings
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/6bb83c16c8fa725b.
Report an issue: GitHub.