The Puppet Labs Issue Tracker has Moved:

This issue tracker is now in read-only archive mode and automatic ticket export has been disabled. Redmine users will need to create a new JIRA account to file tickets using See the following page for information on filing tickets with JIRA:

Bug #16116

Arrays and hashes are mutable; new members can be added and existing values changed

Added by Nick Fagerlund over 3 years ago. Updated over 2 years ago.

Status:AcceptedStart date:08/24/2012
Priority:NormalDue date:
Assignee:-% Done:


Target version:3.x
Affected Puppet version: Branch:

We've Moved!

Ticket tracking is now hosted in JIRA:

This ticket is now tracked at:


Courtesy Henrik: Puppet doesn’t let you reassign variables within a given scope, but it lets you change the values of hashes and arrays by mucking with their members. That seems wrong.

$myary = ['zero', 'one', 'two']
$myhash = {first => 'one', second => 'two', third => 'three'}

$myary[3] = 'three' #can insert new element 
$myary[3] = 'something else' #can reassign

$myhash[fourth] = 'four' #can insert new element
$myhash[fourth] = 'something else' #can't reassign, fails compilation

$myary += ['four'] #can't append in same scope, fails compilation

AND it’s inconsistent, so obviously SOMETHING is whacked, even if we actually do want these objects to be mutable.

I don’t know what we should do about this. I think the extent to which this is being used in the wild is completely unknown.


#1 Updated by Anonymous over 3 years ago

  • Category set to language
  • Status changed from Unreviewed to Accepted
  • Target version set to 3.x

This is completely unwanted behavior.

[14:27:51][Ruby(ruby-1.9.3-p125)][Git(3.x)] andy:puppet
> puppet apply -e '$a = [1, 2] $a[0] = 3 notice($a)'
Scope(Class[main]): 3 2
Finished catalog run in 0.18 seconds

#2 Updated by Jan Vansteenkiste over 3 years ago

Probably related, when changing a hash in a erb template, the data structure also gets modified for any other template that uses the same hash.

You can find a (minimal) example here (gist). In this case, the workaround was to use .clone after getting the hash using scope.lookupvar.

#3 Updated by Henrik Lindberg about 3 years ago

Looked at the logic again. You are currently allowed to set the value of a hash key if it is not already set. For an array, it is always allowed to set a value.

So, this is both inconsistent and really bad.

#4 Updated by Frederic Schaer over 2 years ago


I was hit by that one today, so I’d like to add it’s even still possible to delete hash keys using ERBs. Another (bad) thing : it seems the mutability warning disappeared from the “latest” doc, whereas it’s still present for 2.7. See:


The following code will print a hash, delete a key in an inline template (this was my issue with 2 modules using the same source hash), and print the stripped hash :

class mytest::sub::class::one {
    'test1'=>{key1 => $var},
    'test2'=>{key1 => "$var"},
    'test3'=>{key1 => 'thanks'},

class mytest2 {
  include mytest::sub::class::one
  notify {'test2':
    message => inline_template('
11 <%= @hash.inspect %>
  notify {'test':
    message => inline_template('
22 <% @newlist = @hash.delete_if{|k,v| v["key1"]!="cheers"} %>hash : <%= @hash.inspect %>
22 newlist : <%= @newlist.inspect %>


include mytest2

This results in :

11 {"test2"=>{"key1"=>"cheers"}, "test1"=>{"key1"=>"cheers"}, "test3"=>{"key1"=>"thanks"}}

22 hash : {"test2"=>{"key1"=>"cheers"}, "test1"=>{"key1"=>"cheers"}}
22 newlist : {"test2"=>{"key1"=>"cheers"}, "test1"=>{"key1"=>"cheers"}}

#5 Updated by Nick Fagerlund over 2 years ago

Well, ERBs are a special case, and you can do all KINDS of horrible stuff in there, including reassigning scalar variables. :/

#6 Updated by Anonymous over 2 years ago

Redmine Issue #16116 has been migrated to JIRA:

Also available in: Atom PDF