Magical Encoder (HMN)
A text encoder that caches its work so tweaks are instant
- clip
- LoRABox
- model
- CONDITIONING
- CLIP or not
- MODEL or not
The Magical Encoder is the workhorse of this pack - the node LoRABox and the whole Mojo system were built around it. It's a text encoder on steroids: it can load up to four separate text encoders, apply a LoRABox stack before encoding, and - the headline feature - save its conditioning to disk and reuse it when the text hasn't changed. If you iterate on a workflow where the same prompts get encoded over and over while you tune sampler settings, this removes the re-encode from every single iteration. Text encoding is usually cheap, but with big T5-style encoders it stops being free.
The inputs that matter
- text - the prompt, multiline. The thing being encoded.
- Encoder_1 / Encoder_2 / Encoder_3 / Encoder_4 - dropdowns into your
text_encodersfolder. You can chain up to four, withuse_Encoder_2/3/4toggles switching each extra one on. This is how you feed a multi-encoder model (CLIP + T5 + ...) from raw encoder files. - clip (optional) - if you wire a CLIP in here, the node uses it and ignores the encoder dropdowns. The "CLIP or not" output exists so you can chain this node: pass one encoder's clip into the next, and encoders load once instead of once per node.
- LoRABox (optional) - plug a LoRABox stack in and it applies every active LoRA to the model and clip before encoding. The
modelinput is needed if your box contains model LoRAs. - model_type - tells the loader which CLIPType the encoders belong to:
stable_diffusion,sd3,ltxv,flux-adjacent options,ace, and more. Get this wrong and the encoders load with the wrong expectations. - clip_skip - default -2, applied to freshly loaded encoders. On SD 1.5-style models this is the familiar anime convention; on SDXL it does little; on LLM-encoder models it doesn't exist. Set it where your model lineage expects it.
- Active / Override - the buffer controls. Active on + a matching buffer on disk + Override off = load from disk, no encoding. Override on = always re-encode (and overwrite the buffer).
- Output_Path / Name - where the buffer lives:
output/<Output_Path>/<Name>.conditioning. Defaults to a dated folder and "Buffer".
How it works
When it needs to encode, the node either uses your wired clip or builds one from the listed encoder files, applies the LoRABox, tokenizes and runs encode_from_tokens_scheduled, then serializes the conditioning tensor plus its extra variables into a safetensors .conditioning file. On a later run, if the file exists and you haven't forced Override, it loads that file instead of touching the encoders. Note the buffer is keyed to the file path - not to the text. That's the feature and the trap.
Where people get burned
The #1 confusion: you edit the prompt text, re-queue, and get the old conditioning. That's the cache doing its job, and the fix is flipping Override on once to refresh the buffer, then back off. It's a deliberate design - the buffer survives across runs so you can hammer the sampler without re-encoding - but it will absolutely confuse you the first time. Also note the default [time(%Y-%m-%d)] Output_Path means buffers are day-scoped; yesterday's buffer is quietly not found, which is good for freshness and mildly annoying if you expected persistence.
Installing it
Hellrunner's Magical Nodes, one install. ComfyUI Manager → search "Hellrunner's Magical Nodes", or:
cd ComfyUI/custom_nodes
git clone https://github.com/Hellrunner2k/ComfyUI-HellrunnersMagicalNodes.git
Restart ComfyUI. No extra pip dependencies - it uses ComfyUI's own encoder loading.
Troubleshooting
- Stale output after editing text? Flip Override on, queue, flip it off. Cache refreshed.
- "clip input is invalid: None" error? No CLIP wired and no encoder selected, or the selected encoder files don't contain a valid text encoder. Check Encoder_1 and model_type.
- Encoders acting wrong?
model_typemust match the actual encoder architecture - a T5 loaded asstable_diffusionwill misbehave. Andclip_skiponly applies to newly loaded encoders, so it won't retroactively change a clip you wired in. - Buffers multiplying in dated folders? That's the
[time(%Y-%m-%d)]default; set Output_Path to a fixed folder if you want one buffer location.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| Active | BOOLEAN | true | Boolean On/Off Switch for better integration in complex flows |
| Output_Path | STRING | [time(%Y-%m-%d)] | Subfolder Path into "output" |
| Name | STRING | Buffer | Buffer File Name (Name.conditioning) |
| Override | BOOLEAN | false | Force override the buffer |
| text | STRING | The text to be encoded. | |
| Encoder_1 | COMBO | The Encoder_1 used for encoding the text. | |
| use_Encoder_2 | BOOLEAN | false | Enable second encoder |
| Encoder_2 | COMBO | The Encoder_2 used for encoding the text. | |
| use_Encoder_3 | BOOLEAN | false | Enable 3rd encoder |
| Encoder_3 | COMBO | The Encoder_3 used for encoding the text. | |
| use_Encoder_4 | BOOLEAN | false | Enable 4th encoder |
| Encoder_4 | COMBO | The Encoder_4 used for encoding the text. | |
| clip_skip | INT | -2-128–-1 | Last Layer |
| model_type | COMBO | Model Type to load encoders for. | |
| load_device | COMBO | 2 options: default, cpu | |
| clipopt | CLIP | The CLIP model used for encoding the text. | |
| LoRABoxopt | LORABOX | LoRABox | |
| modelopt | MODEL | The model to apply the LoRABox to |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| CONDITIONING | CONDITIONING | Conditioning |
| CLIP or not | CLIP | Used Clip, if encode happens. Used for chaining encoders so loading does not happen multiple times |
| MODEL or not | MODEL | Used Model, if LoRABox is not empty |