Environment Variable
Keep Your API Keys Out of the Workflow (and Get Machine-Specific Prompts)
- value
The Environment Variable node from wtesler/ComfyUI-EnvVariable does exactly one thing: it reads an environment variable by name and hands you the value as a string. That's it. One input, one output, about twenty lines of Python. Don't expect a settings panel or a .env file parser - this is the whole pack.
So why does it exist? Because of a dirty little habit ComfyUI workflows have: hardcoded secrets. People paste their API keys, tokens, and local paths straight into widget text, then upload the .json to Civitai or share it on r/comfyui. Congratulations, you've just shipped your key to the world. An env var breaks that chain - the workflow file contains nothing but the name of the thing, and the actual value lives on your machine. Same trick works when the same workflow has to behave differently per machine: a home box and a rented GPU box can read the same template and each resolve their own paths, usernames, or endpoints.
How it works
The mechanism is gloriously simple, so it's worth understanding precisely. When the node runs, it does a straight lookup of os.environ[key] in the ComfyUI process. Present → returns the value as a STRING. Missing → it raises KeyError with the message Environment variable '<key>' was not found. and your queue run dies.
The practical consequence: this is read at execution time, but from the process's environment - which is frozen when ComfyUI starts. Changing a variable while ComfyUI is already running does nothing until you fully close and relaunch the app. The README calls this out explicitly, and it's the #1 thing people trip over.
There's no nesting or interpolation here. os.environ doesn't recursively expand values, so you can't build $HOME/foo chains through this node and expect them to resolve like a shell would. It reads, it returns, done.
The one input and the one output
The only input is key, a single-line STRING with the default ENV_VARIABLE_KEY. You type the variable name, not $VAR or ${VAR} - just the bare key. Toggle the default off and type something like CIVITAI_TOKEN or MODEL_DIR.
The output is value, a STRING. Wire it into anything that takes text: prompt text fields, API-call nodes, path inputs. Since a lot of nodes in the ecosystem (LLM clients, image-hosting uploaders, model downloaders) accept API keys as strings, this is usually the missing middle step between "key in your shell profile" and "key in the node".
Install
No requirements, no model downloads, no extra dependencies - pyproject.toml is literally empty on dependencies. Two ways in:
ComfyUI Manager (easiest): search for ComfyUI-EnvVariable in Custom Nodes Manager and install. There's nothing to download beyond the node itself.
Manual clone:
cd ComfyUI/custom_nodes
git clone https://github.com/wtesler/ComfyUI-EnvVariable.git
Then restart ComfyUI. (Or hit Manager's restart, or the "Reload Custom Nodes" if your build has it - for a node this small, a reload is usually fine.) Set the variable in your launch script before ComfyUI starts - set MY_KEY=... on Windows, export MY_KEY=... on Linux/macOS - then fully restart the process.
Common issues
"Environment variable 'X' was not found" - that's the KeyError above, and it's always one of three things: a typo in the key, the variable never actually got set, or you set it but didn't fully restart ComfyUI. The first two are on you; the third is the classic trap. Close the app entirely and relaunch.
The node works, but your downstream node sees an empty/garbage value - check whether the variable was set in the right shell. If you exported it in one terminal and launched ComfyUI from a different one (or a service manager, or a desktop shortcut), the process never saw it. Environment is inherited at process launch, not discovered later.
It crashes your whole run when a key is missing - yes, that's by design; there's no fallback or "use default" branch. If you need graceful failure, that's a job for a different node. The honest trade-off of a node this small: it's predictable, and it fails loudly rather than silently injecting the wrong string.
Is this the most exciting node in your workflow? No. But it's the one that stops you from leaking a key in a shared file, and for that alone it earns a spot in your template.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| key | STRING | ENV_VARIABLE_KEY | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| value | STRING | — |