os.path.join
The path-builder you'll actually use every single day
- a_in
- b_in
- c_in
- d_in
- path
Every other node in this path family answers questions about a path. This one builds paths, and it's the node you'll actually use every single day. os.path.join is how you stop hand-typing outputs/my_project/{date}/frame_{n}.png into four different saver widgets and start assembling the path from parts - which means one change upstream fixes every consumer at once.
It's from the ovum/path/os.path family in comfy-ovum, and it mirrors Python's os.path.join(): it glues path components together with the right separator for your OS, without you worrying about trailing slashes or double slashes.
How it works
You feed it up to four components (a–d), each of which can be a widget value or a linked value, and it returns one joined STRING (path). The inputs that matter:
- a (STRING, required): the first component - typically your base directory, like
ComfyUI/outputor the value from comfy-ovum's Folder Paths node. - b, c, d (STRING, optional): further components, appended only if non-empty.
- a_in, b_in, c_in, d_in (PATHLIKE,STRING, optional): link-only jacks, one per component. A connected value overrides the matching widget, so you can mix typed base paths with dynamic middle segments from other nodes.
- forward_slashes (BOOLEAN, default false): if true, the result gets backslashes converted to forward slashes.
One STRING out. That's the whole node - and it's the reason your output paths stop breaking.
The pattern
This is where comfy-ovum's design shines. Wire a Folder Paths node (or a fixed base path) into a, run a date or project-name string into b, a counter into c, and your saver gets a path that's assembled, not typed. Change the project name once and every downstream node re-targets. Because components are only joined when non-empty, you can leave d blank and the path stays clean.
The forward_slashes toggle exists because sfinktah clearly runs ComfyUI on Windows-adjacent setups (his other work is the amd-torch guide for running ComfyUI on AMD/ROCm under Windows). If you ever hand these paths to tools that choke on backslashes - Python code, some loaders, URLs - flip it and the whole chain stays /-separated.
Installing it
Pack-wide install, once:
cd ComfyUI/custom_nodes
git clone https://github.com/sfinktah/comfy-ovum
Or ComfyUI Manager → "comfy-ovum" → Install → restart. No models, no extra deps for this node.
Gotchas
- Joining is not normalizing.
os.path.joincleans up separators but won't resolve..or.- that'sos.path.normpath's job. If you're feeding in path fragments from user input, run the result through the normpath node before using it. - An absolute later component wins. Standard
os.path.joinbehavior: ifbstarts with a slash (or drive letter on Windows), it replaces everything before it. That's usually what you want for override-style paths, but it can silently discard your base directory if a component arrives with a leading slash from upstream. - The widget is the fallback, the link is the source of truth: if you have a value wired into
a_in, typing inadoes nothing.
Between this and os.path.split/splitext, you can build and decompose every path your workflow touches. Start assembling output paths with it and you'll wonder how you tolerated per-node hardcoding.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| a | STRING | — | |
| a_inopt | PATHLIKE,STRING | — | |
| bopt | STRING | — | |
| b_inopt | PATHLIKE,STRING | — | |
| copt | STRING | — | |
| c_inopt | PATHLIKE,STRING | — | |
| dopt | STRING | — | |
| d_inopt | PATHLIKE,STRING | — | |
| forward_slashesopt | BOOLEAN | false | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| path | STRING | — |