puppetlabs/puppet · error · TypeConversionError
odd number of arguments for Hash
Error message
odd number of arguments for Hash
What it means
The new() function on Puppet's Hash type can build a hash from a flat array of alternating keys and values (implemented with Hash[*from]). Ruby's Hash[] semantics require an even number of elements, so an odd-length array raises TypeConversionError with Ruby's classic 'odd number of arguments for Hash' wording. An empty array yields {} and a Hash passes through unchanged; only the flat array/iterable path with an odd count fails.
Source
Thrown at lib/puppet/pops/types/types.rb:2849
else
result.merge!(value)
end
else
r = path[0..-2].reduce(result) { |memo, idx| (memo.is_a?(Array) || memo.has_key?(idx)) ? memo[idx] : memo[idx] = {} }
r[path[-1]] = (all_hashes ? PHashType.array_as_hash(value) : value)
end
end
result
end
def from_array(from)
case from
when Array
if from.size == 0
{}
else
unless from.size.even?
raise TypeConversionError, _('odd number of arguments for Hash')
end
Hash[*from]
end
when Hash
from
else
if PIterableType::DEFAULT.instance?(from)
Hash[*Iterable.on(from).to_a]
else
t = TypeCalculator.singleton.infer(from).generalize
raise TypeConversionError, _("Value of type %{type} cannot be converted to Hash") % { type: t }
end
end
end
end
end
View on GitHub (pinned to e227c27540)
Solutions
- Fix the source data so every key has a value.
- Check the count before converting and fail with a message that shows the array: if size($flat) % 2 != 0 { fail(...) }.
- Truncate deliberately when a trailing element is known garbage: $flat = $flat[0, (size($flat) / 2) * 2].
- Build the hash from real 2-element pairs instead of a flat list, e.g. reduce over each_slice(2).
Example fix
# before (Puppet DSL)
$flat = split($content, ' ') # may end up odd after bad input
$h = Hash.new($flat) # TypeConversionError when odd
# after
if size($flat) % 2 != 0 {
fail("expected key/value pairs, got odd array: ${flat}")
}
$h = Hash.new($flat) Defensive patterns
Strategy: validation
Validate before calling
# Ruby
raise ArgumentError, 'odd pair array' unless flat.size.even?
# Puppet DSL
if size($flat) % 2 != 0 { fail('odd number of elements; expected key/value pairs') } Type guard
def even_pair_array?(a) a.is_a?(Array) && a.size.even? end
Try / catch
begin h = Hash.new($flat) rescue Puppet::Error # repair by dropping the dangling element, then retry h = Hash.new($flat[0, (size($flat) / 2) * 2]) end
Prevention
- Validate size % 2 == 0 before any flat-array-to-hash conversion.
- Prefer arrays of 2-element pairs (or real hashes) in module interfaces instead of flat key/value lists.
- Log the offending array when validation fails so bad input is visible.
When it happens
Trigger: Hash.new(['a', 1, 'b']) in a manifest; Hash.new($flat) where $flat came from split() and has an odd element count; converting any iterable whose element count is odd via Hash.new.
Common situations: Parsing key/value tokens out of a config line where a trailing element or malformed input makes the count odd; module parameters accepting flat pair lists from Hiera; glue code that flattens pairs from another data source and loses one element.
Related errors
- Value of type %{type} cannot be converted to Hash
- Illegal format '#{actual}' specified for value of Hash type
- Unable to convert a #{version_range.class.name} to a SemVerR
- Unable to convert a #{version.class.name} to a SemVer
- Unable to create a #{impl_class.name} from a #{arg.class.nam
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/85b8ded91ffac21a.
Report an issue: GitHub.