When are expanding arguments actually allowed?

I have built a list of maps which I would like to combine into a single map. I thought I could easily do something like merge(local.listOfMaps...) which fails with The expanding argument (indicated by ...) must be of a tuple, list, or set type.
If I attempt to force the conversion via tolist it fails with the same error.

Is there some inherent reason why it doesn’t see it as a list?

Hi @fraenkel!

What exactly was the error when you tried to use tolist(local.listOfMaps)? Was it still the one you mentioned here starting with “The expanding argument …”, or was it an error specifically with the tolist function?

It seems like local.listOfMaps isn’t actually a sequence for some reason, and I’m hoping that the tolist call will give some additional context about it.

The error The expanding argument (indicated by ...) must be of a tuple, list, or set type. is what I get with or without tolist(). The local.listOfMaps is actually a list returned from flatten which must be a list.

Thanks for the additional context, @fraenkel!

I tried a few different permutations locally to see if I could reproduce this, but I couldn’t find an example that would produce this error. Do you think you could share a more complete example of the problem that I might be able to run locally to debug it? I assume there must be something unusual about this local.listOfMaps value that I’m not thinking of to test.

Here is a minimal reproducer:

variable "mapping" {
  default = {
    "a" = ["b", "c"]
  }
}

locals {
  mapping = [
    for x, y in var.mapping : [
      for z in y : {
        "${z}" = x
      }
    ]
  ]
}

output "x" {
  value = merge(flatten(local.mapping)...)
}

Thanks for the reproduction case, @fraenkel! I was able to see the same result as you, and so I’ve opened a GitHub issue to track this:

I think the problem here is that the argument expansion mechanism isn’t correctly handling the case where the type of the argument isn’t known yet, which is true during the validation step. The type is unknown in this particular case because variables are treated as unknown during validation (a module must be valid for any value of the variable’s type).


The transform you are doing here is almost the same as the built in function transpose, so you might be able to work around this bug by deriving your result from that function’s result.

Depending on how you had intended to deal with any duplicate keys in the result (or, if duplicates are valid at all), something like this might work:

output "y" {
  value = { for k, v in transpose(var.mapping) : k => v[0] }
}

That will work. Thanks.