# Fix terraform "Error: Value for undeclared variable"

**TL;DR:** You passed a `-var` or tfvars value for a variable the root module never declared. Either add a `variable` block at the root (and pass it through to the child module that actually uses it) or drop the stray value. Also check shell quoting: a space around `=` or stray quotes becomes part of the variable name.

## The error

```text
Error: Value for undeclared variable

A variable named "environment" was assigned on the command line, but the root module does not declare a variable of that name. To use this value, add a "variable" block to the configuration.
```

## Steps

1. Compare the name in the error to your `variable` blocks. Expected: you spot a typo, or confirm the variable only exists in a child module.
2. If the value belongs to a child module, add a root-level pass-through:
   ```hcl
   variable "environment" {
     type    = string
     default = "dev"
   }
   module "webserver_cluster" {
     source      = "./modules/webserver-cluster"
     environment = var.environment
   }
   ```
   Expected: the root declares it and forwards it.
3. If the value was a mistake (for example passed to `terraform init` when it was meant as a backend setting), remove that `-var`. Expected: the error names nothing.
4. On Windows `cmd.exe`, single quotes are not quoting characters. Use double quotes with escaped inner quotes, or a tfvars file. Expected: the variable name in the error no longer starts with a stray quote.

## When this applies

- `plan`, `apply`, or (on newer CLI versions) `init` fails naming a variable "assigned on the command line" that the root module does not declare.
- The variable is declared inside a module but you passed the value at the root.

## When it does NOT apply

- "No value for required variable". That means the variable IS declared but has no value. Opposite problem.
- "Variables not allowed". That is about interpolation inside the `backend` block, not input variables.

## Tool and version compatibility

- Terraform CLI 0.12+ through 1.x. Note Terraform 1.15 validates input variables during `init` more strictly than 1.14, so stray `-var` flags that used to be ignored at init now fail there.

## Why it happens

Command-line and tfvars values land only in the root module. Child module variables are invisible from the CLI; the root must declare a variable and explicitly pass it into each `module` block. There is no implicit forwarding.

## Edge cases and pitfalls

- Terraform Cloud "Terraform Variables" vs "Environment Variables" are different things. Provider-auth values like the OIDC env vars must be environment variables; setting them as Terraform variables produces this error.
- A space in `-var "length = 2"` makes the name `"length "` with a trailing space. Terraform takes the name literally.