Character Reference Latent
How FLUX.2 Actually Sees Your Character
- conditioning
- refs
- vae
- conditioning
FLUX.2 is why the Omnichar pack exists - Klein 9B is the model the author's own reference workflow is built around. Klein doesn't take reference pictures in numbered slots like a video model does. It takes them as latents, stapled onto the conditioning, and this node is the stapler.
Why there's a node for this at all
The stock way to do it is a chain: one Set Reference Latent node per reference image, wired in order, positive and negative. Works fine with two references. Get to six and your graph is a ladder of near-identical nodes that are easy to wire in the wrong order, and the order is the thing your prompt's numbering depends on. This collapses the ladder into one node that consumes the whole resolved reference list.
You'll find this in community Klein workflows too - the phrase "multiple reference latents" is how people describe the same idea, and the kv-fp8 checkpoints plus the Flux KV cache node exist because multi-reference edits keep recomputing attention keys and values for the references.
The mechanism, briefly
For each reference it opens the image, encodes it through the VAE you handed it, collects the results into a list, and appends that list to the conditioning under reference_latents - one append of the entire list, the same way ComfyUI's own multi-reference nodes do it. Nothing is resized or composited first; the images arrive as Decode Character resolved them.
Inputs and outputs
conditioning is your positive (or negative) conditioning from a text encode. refs is the CHARACTER_REFS wire from Decode Character, which means the same setting you chose there - arch, max_references - decides exactly what the model sees. vae is the field to get right: use the model's own VAE. A Klein reference latent encoded with anything else is noise wearing your character's clothes.
One output, conditioning. Wire it into your sampler, and wire it into the negative as well - the node description says so outright, and graphs that skip the negative are the single most common way to get a character that only half-holds.
So the shape of a Klein character graph is: Load Character → Decode Character → two Character Reference Latent nodes, one on the positive, one on the negative, both off the same refs.
Install
ComfyUI Manager, search Omnichar - or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/omnichar/ComfyUI-Omnichar
cd ComfyUI-Omnichar
pip install -r requirements.txt
Restart, drop .char files in ComfyUI/models/characters/. No extra weights to fetch.
Common issues
If refs is empty, the error is "Decode Character sent no references" - go fix the cap or the reference set on Decode rather than poking this node. That check exists because attaching nothing would otherwise render a perfectly normal but totally uncharactered image, which is a confusing way to lose an afternoon.
Cost scales with the number of references, since every one of them is a VAE encode and a longer conditioning context. Four references is fine on a mid-range card. Ten - FLUX.2's ceiling is up there - is where people start asking why their render doubled in length. If a character has more references than the frame can use, cap it on Decode, where the trim is split between face, body and wardrobe instead of cutting the tail off your outfits.
And the honest caveat: reference latents give the model something to look at, not a guarantee. The KB is blunt that keeping a face locked across a chain of edits is still the hard part of 2026, and a mask around the edit does more for identity drift than any amount of re-prompting.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| conditioning | CONDITIONING | — | |
| refs | CHARACTER_REFS | — | |
| vae | VAE | Encodes each reference. Use the model's own VAE. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| conditioning | CONDITIONING | — |