**TL;DR:** Define the missing variable before you build. mkdocs-macros raises "Error: undefined variable" when a markdown page uses a Jinja expression like {{ deploy_url }} that is not registered in the macro context. Add the name under `extra:` in mkdocs.yml for static values, or register it in a macro module for computed values, then rebuild.

```text
Error: undefined variable 'deploy_url'
```

1. Get the exact variable name from the build log:
   ```
   mkdocs build 2>&1 | grep "undefined variable"
   ```
   Expected: one line naming the variable, e.g. `Error: undefined variable 'deploy_url'`.
2. Open mkdocs.yml and add the variable under `extra:`:
   ```yaml
   extra:
     deploy_url: "https://example.com/docs"
   ```
3. If the value must be computed (dates, git metadata, file contents), define it in a macro module instead. Create `main.py` in the project root:
   ```python
   def define_env(env):
       env.variables["deploy_url"] = "https://example.com/docs"
   ```
   and register it in mkdocs.yml:
   ```yaml
   plugins:
     - macros:
         module_name: main
   ```
   Skip this step if you used `extra:` in step 2.
4. Rebuild:
   ```
   mkdocs build
   ```
   Expected: the build completes with no errors and the `site/` directory contains the rendered pages.
5. Open the built page and confirm the variable rendered where the template used it.

## Use this when
- `mkdocs build` fails with `Error: undefined variable`
- A template expression like {{ some_name }} aborts the build and the log names that variable
- You added a macro variable to markdown but never registered it

## Not for this skill when
- The error is a Jinja syntax error like "unexpected end of template" - that is malformed markup, not a missing variable
- The undefined name sits inside a fenced code block that should not be evaluated at all
- A different plugin fails the build with its own error message

## Variant phrasings
- "mkdocs macros undefined variable error"
- "Error: undefined variable in mkdocs build"
- "jinja2 undefined variable mkdocs-macros"

## Why it happens
mkdocs-macros renders markdown through Jinja with strict undefined handling, so any name that is not a registered variable, macro, or filter is a hard error instead of rendering blank. The variable usually lived in an older config, a deleted `extra:` entry, or a macro module that is no longer loaded.

## Edge cases
- Variables set in a page's YAML front matter are visible only on that page; shared snippets need the variable in `extra:` or the macro module.
- A variable from a macro module disappears if the module fails to import - look for an import error above the undefined-variable line in the build log.
- Environment variables are not picked up automatically; assign them explicitly in `define_env` or `extra:`.
- Names are case-sensitive: `deploy_url` and `Deploy_Url` are different variables.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_YCXgd8T8t_oNqTYg4zrwpw
