XAnyToString
The node that answers 'what the hell is actually on this wire?'
- anything
- anything
- string
- xdata_string
Every ComfyUI user hits the same wall eventually: some node hands you data, you have no idea what's in it, and ComfyUI's built-in text display won't accept the wire type. XAnyToString is the blunt instrument for that moment. It takes any input, runs Python's str() on it, and hands you a plain STRING you can print, save, or feed into a filename - while also passing the original data through untouched so nothing downstream breaks.
How it works
The mechanism is as honest as it gets. The anything input is a MatchType port, so it accepts any type. At execution it does str(anything) and wraps the result in three outputs:
- anything - the original input, passed through with its type preserved.
- string - the
str()conversion of that input. - xdata_string - the same text repackaged into the pack's
xdata_stringpayload format, ready to feed XDataSave for logging to its SQLite history.
There's no magic, no pretty formatting. The source literally catches the exception case: if str() fails it raises a clear "Failed to convert input to string" error instead of silently dying.
What it's actually good for
Set expectations before you get excited about that "anything" port. str() on a number, a path string, a seed, or a small dict gives you something readable and useful - "42", "output/Images/foo.png", {'seed': 42}. str() on a MODEL or an IMAGE tensor gives you the Python repr, which is an object address and a shape, not a description. So don't reach for this expecting a caption generator. Reach for it when you want to:
- Turn a seed or a resolution into text for a filename or a marker.
- Inspect what a custom node is actually outputting - plug it in front of a Show Text and read the repr.
- Convert a small value into a string you can log with XDataSave or slot into XMarkdownSave.
Using it
One input, three outputs. Wire anything in, grab whichever output you need. The pass-through output is the underrated one: because the node also returns your original data unchanged, you can drop it into a wire purely for side-effect logging without changing the graph's behavior at all. That's the pattern worth stealing - a "tap" node that observes without interrupting.
Installing it
XAnyToString ships in ComfyUI-Xz3r0-Nodes, so one install covers it. Use ComfyUI Manager (search ComfyUI-Xz3r0-Nodes), or:
cd ComfyUI/custom_nodes
git clone https://github.com/Xz3r0-M/ComfyUI-Xz3r0-Nodes.git
cd ComfyUI-Xz3r0-Nodes
pip install -r requirements.txt
Then restart ComfyUI. This node itself has no extra dependencies - it's pure Python stdlib - but the pack as a whole wants ffmpeg-python and system FFmpeg if you touch its audio/video nodes.
Gotchas
Two honest caveats. First, str() of complex objects is rarely what you want to ship to a filename - sanitize it before you build paths, because the pack's save nodes reject path separators and traversal tricks anyway. Second, the node is a one-shot conversion: there's no formatting control, no truncation, no JSON pretty-print. If you need those, keep an eye out for a dedicated string-formatting node instead. It's a simple tool, and for the "what's on this wire" job, simple is the point.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| anything | COMFY_MATCHTYPE_V3 | Pass-through input. The pass-through output keeps the same data type as this input while also converting the value with Python str() |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| anything | COMFY_MATCHTYPE_V3 | Original input data passed through for downstream nodes |
| string | STRING | String converted from the input using str() |
| xdata_string | xdata_string | xdata_string payload for XDataSave |