# Fix terraform "Error: Module not installed"

**TL;DR:** You added a `module` block, or changed a module's `source`, after the last `terraform init`. Module installation happens only during init; `plan` never installs. Run `terraform init` again, and re-run it every time you touch a module block.

## The error

```text
Error: Module not installed

  on main.tf line 11, in module "ada":
  11: module "ada" {

This module is not yet installed. Run "terraform init" to install all modules required by this configuration.
```

## Steps

1. Run `terraform init`. Expected: output shows the new module being installed into `.terraform/modules`, ending with `Terraform has been successfully initialized!`
2. If you changed a `source` (new registry version, new git ref), run `terraform init -upgrade` so the cached copy is refreshed. Expected: the module is re-downloaded at the new source.
3. Verify the install manifest: check `.terraform/modules/modules.json` lists your module. Expected: it is there.
4. Run `terraform plan`. Expected: the plan proceeds instead of erroring.

## When this applies

- `plan` or `apply` fails with "Module not installed" right after you added a module block, changed its `source`, or cloned the repo fresh.
- CI pipelines that run `plan` without an `init` stage fail the first time anyone adds a module.

## When it does NOT apply

- Registry resolution errors for a module source ("module not found"). That is a source-address problem, not a missed init.
- Backend initialization errors. Those are about state storage, not module code.

## Tool and version compatibility

- All Terraform CLI versions. The init-installs-modules rule predates 0.12 and is unchanged.

## Why it happens

`init` copies or links each child module into `.terraform/modules` and records it in the manifest. `plan` and `apply` only read that manifest; they never fetch. A module block added after init is simply unknown to the working directory until init runs again.

## Edge cases and pitfalls

- Changing only the module's `version` or git `ref` still requires re-init; the cached copy is pinned to the old one.
- Every CI pipeline needs a dedicated `terraform init -input=false` stage before plan. It is cheap and idempotent, and it also downloads any new providers the module pulls in.