Any to String
The node you add when a socket turns red
- value
- string
You have a number. You need text. ComfyUI's type system says no, and you get the red wire and the "cannot convert" wall. Any to String is the smallest possible fix: one wildcard input, one STRING output, no settings to get wrong.
It lives in Orel's Nodes, a utility pack by DarkOrel whose entire pitch is that you shouldn't have to install five packs for plumbing. This node is the purest example of that pitch.
What it actually does
The input is declared as * - ComfyUI's IO.ANY, the wildcard type. Wiring anything into it passes validation, and from there the node stringifies whatever it received:
Nonebecomes""(empty string, not the text "None")- booleans become
True/Falsewith capital letters, Python-style - not the lowercasetrueyou'd see in JSON - strings pass through untouched
- everything else goes through Python's
str()
That last line is where the trap lives, and it's worth knowing before you wire something silly into it. str() never fails. Point it at an image tensor, a MODEL, or a LATENT and it will happily hand you back torch.Size([1, 1024, 1024, 3]) or a <comfy.model_patcher.ModelPatcher object at 0x7f...> string with a memory address in it. The wildcard socket means ComfyUI won't stop you. You are the type checker here.
When you'd reach for it
Three real cases, all of them plumbing:
Feeding a text node from a number. Trigger words, prompt templates, filename builders and the rest of this pack's text side all want STRING. A seed, a score, or a width lives as INT/FLOAT. This is the adapter.
Making a value visible. Wire a float into Any to String and out to a text preview node and you're watching that value during a run instead of guessing. Cheap, and it beats printing to console.
Threading metadata through a workflow. The whole reason the plumbing layer exists, per the ecosystem's own reference material, is to fight repetition and illegibility: one source, many consumers. If a seed needs to reach the sampler, the filename and a note, you convert once and fan out.
Inputs and outputs
Honestly, there's one of each.
value(required, type*) - whatever you're converting.- string (STRING) - the result.
Installing it
ComfyUI Manager → search Orel's Nodes (orels-nodes) → Install → restart → hard-refresh the browser. That's the whole ritual.
Manual, if you prefer git:
cd ComfyUI/custom_nodes
git clone https://github.com/DarkOrel/Orels-Nodes.git orels-nodes
python -m pip install -r orels-nodes/requirements.txt
Then restart ComfyUI and hard-refresh. Note that this node itself needs nothing from requirements.txt - that file is huggingface_hub and filelock, which exist for the pack's model-download nodes. The primitives are pure Python and load even on a bare install with no optional packages present.
Gotchas
It's not a number formatter. A float 0.6000000000000001 comes out with all its digits. If you want presentation, don't expect this node to round for you.
Booleans are True/False. If you're building a string that another tool parses - a JSON blob, an argument list - those capitals will break it. There's no lowercase mode.
The wildcard only affects this socket. A common misconception: since this node accepts *, some people assume the whole graph loosened up. It didn't. Every other socket still type-checks exactly as before. Which is the better design anyway - a graph where nothing type-checks is a graph you can't debug.
Don't use it to smuggle a list. A list of five strings becomes "['a', 'b', 'c', 'd', 'e']" - a Python repr, not five lines. If you wanted a join, you wanted a different node.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| value | * | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| string | STRING | — |