# Fix terraform "Error: Invalid function argument"

**TL;DR:** A built-in function rejected one of its arguments. Read which function and which parameter failed (terraform names both), then test the call in `terraform console` until it returns what you expect. Most cases are wrong types, impossible values (bad CIDR math), or paths that do not resolve.

## The error

```text
Error: Invalid function argument

  on main.tf line 12, in resource "aws_subnet" "a":
  12:   cidr_block = cidrsubnet("CONTAINER_IP/16", 12, 1)
      +----------------
      | while calling cidrsubnet(prefix, newbits, netnum)

Call to function "cidrsubnet" failed: prefix length not suitable for given
address: prefix length 28 is too large for the specified address CONTAINER_IP/16.
```

## Steps

1. Read the `while calling` line. It names the function and the failing parameter. Open `terraform console` and reproduce the call:

   ```bash
   terraform console
   > cidrsubnet("CONTAINER_IP/16", 8, 1)
   "CONTAINER_IP/24"
   ```

   Expected: you see the failure in isolation, without a full plan.
2. For CIDR math errors, fix the numbers: `newbits` must leave room. `cidrsubnet("CONTAINER_IP/16", 8, 1)` is valid; asking for a /28 out of a /16 with the wrong newbits is not.
3. For `file()` / `templatefile()` failures (`no file exists for ...` or `vars map does not contain key`), check the path is relative to the module (`${path.module}/...`) and that every `${...}` in the template has a matching key in the vars map, spelled exactly (case-sensitive).
4. Re-run `terraform validate`. Expected: `Success! The configuration is valid.`

## When this applies

- `validate`, `plan`, or `console` fails naming a function call: cidrsubnet, file, templatefile, jsondecode, length, contains, lookup, etc.
- You are doing CIDR arithmetic, file loading, or template rendering.

## When it does NOT apply

- `Call to unknown function`. That is a typo in the function name or a function from a newer terraform version, not a bad argument.
- Provider-side errors at apply time. Functions evaluate in terraform core; if the error comes from the provider API, it is not this.

## Tool and version compatibility

- Terraform CLI 0.12+ through 1.x. Function set grows by version; check `terraform version` if docs show a function your CLI lacks.

## Why it happens

Terraform evaluates functions during plan, before any provider runs. It type-checks and value-checks each argument. A wrong type, an impossible value, or a missing file fails fast right there.

## Edge cases and pitfalls

- `file("~/.ssh/key.pub")` fails: terraform does not expand `~`. Use an absolute path or `${path.module}`.
- `templatefile` matches vars strictly. `PROJECT_NAME` in the template and `project_name` in the vars map is a miss; the error names the missing key.
- `contains(list, null)` fails with `argument must not be null`. Guard with `== null ||` before the call.
- `tonumber("abc")` fails because terraform never guesses conversions. Only unambiguous ones (`"8"` to 8) are automatic.