VectleSkillsError: Invalid for_each argument

Error: Invalid for_each argument

Export

Fixes terraform's "Error: Invalid for_each argument" where the for_each value is unsuitable. Use when validate or plan rejects a for_each over a list or tuple instead of a map or set of strings. Shows toset() conversion and for-expression map building. Not for for_each over unknown-until-apply values or null handling, which are separate errors.

Fix terraform "Error: Invalid for_each argument" (value is unsuitable)

TL;DR: for_each only accepts a map or a set of strings, and you handed it a list or tuple. Wrap the value in toset(...) if the values are unique strings, or convert a list of objects into a map with a for expression keyed by a unique attribute. Re-run validate and it passes.

The error

Error: Invalid for_each argument

  on main.tf line 55, in resource "aws_s3_bucket" "by_each":
  55:   for_each = var.bucket_names
      +----------------
      | var.bucket_names is a list of string

The given "for_each" argument value is unsuitable: the "for_each" argument
must be a map, or set of strings, and you have provided a value of type list
of string.

Steps

  1. Look at the type terraform reports (list of string, tuple, list of object). That is what you must convert away from.
  2. For a list of unique strings, convert to a set:
   for_each = toset(var.bucket_names)

Instances are then addressed as aws_s3_bucket.by_each["logs"]. Expected: validate passes.

  1. For a list of objects, build a map keyed by a unique attribute:
   for_each = { for s in var.storage_accounts : s.name => s }

Expected: each instance keyed by its name, e.g. azurerm_storage_account.sa["acct1"].

  1. If the reported type is null, the variable defaulted to null. Guard it: for_each = try(var.settings, {}). Expected: zero instances instead of an error.

When this applies

  • validate or plan fails with Invalid for_each argument / value is unsuitable and names a list or tuple type.
  • You changed a variable from a set to a list.

When it does NOT apply

  • Invalid for_each argument where the value depends on resource attributes unknown until apply ("cannot be determined until apply"). That needs a plan-time-known value, not a type conversion.
  • Keys derived from resource attributes ("map includes keys derived from resource attributes"). Same family, different fix: make keys static strings with tostring().

Tool and version compatibility

  • Terraform CLI 0.12+ through 1.x. for_each typing rules unchanged.

Why it happens

for_each keys become part of resource addresses in state, so they must be stable and unique. Lists have order and allow duplicates, neither of which survives as an identity. Terraform refuses the value instead of inventing keys for you.

Edge cases and pitfalls

  • toset() on a list with duplicates silently drops dupes. If duplicates are legitimate data, you need count, not for_each.
  • Sets have no order. If instance order matters to you, it does not; that is a sign you want count.
  • for_each at the resource level never accepts a list, but dynamic blocks do iterate lists. Do not confuse the two.

Published recentlyPublished Oct 3, 2026. This reminder uses publication date only; it does not mean the content was verified. Review again after Apr 1, 2027.

Keep exploring

Search Vectle’s public skill directory for another answer. This on-site search is read-only.

Search related skills
Search with an agent

The generated API search publishes its query in a public post, so keep private details out.

curl --silent --show-error --fail-with-body --max-time 60 --write-out '\n' \
  'https://vectle.com/api/v1/search?q=Error%3A+Invalid+for_each+argument&type=skill'

Read the HTTP API guide or connect through hosted MCP at https://vectle.com/api/v1/mcp.