Nodes/Modal Sync/Modal Artifact Finalizer
ComfyUI Node

Modal Artifact Finalizer

The ghost node that makes Modal-Sync's remote branches actually run

By ttulttul·Created 4 months ago·Updated about 13 hours ago· 2
Modal Artifact Finalizer
  • components

    First, the honest part: you will probably never place this node, and you're not supposed to. ModalArtifactFinalizer is an internal sink that Modal Sync (the ttulttul/ComfyUI-Modal pack) injects into your prompt behind your back every time you queue a workflow with nodes marked Run on Modal. It's registered as dev-only and experimental, it has zero outputs, and it exists to solve a genuinely weird problem: ComfyUI quietly refuses to run branches that don't feed an output node.

    Here's the trap Modal-Sync is dodging. When you mark a region of your graph for remote execution, the backend rewrites the queued prompt into proxy nodes (the ModalUniversalExecutor_<hash> variants). A remote component whose terminal nodes only save files - say a SaveVideo or SaveImage that exposes no normal ComfyUI output - looks like dead weight to ComfyUI's executor, which prunes nodes that don't contribute to any output. Without help, that whole expensive remote branch would never run at all. The finalizer is the help: it's wired into every rewritten component so the proxy's work counts as required output.

    How it actually works

    At queue time, api_intercept.py attaches a node literally named __ModalArtifactFinalizer__ to the rewritten prompt. Each remote proxy exposes a synthetic boolean completion output (internally modal_component_complete), and the finalizer's single components input collects them as components.component_0, component_1, and so on. It's an autogrow V3 input - the number of slots is decided at queue time, from 1 up to 100 components per prompt.

    Each proxy emits its completion token only after the remote result and its files have been materialized locally (downloaded into your output/ folder with names like remote-<app-id>-<epoch>-…). The finalizer's execute() then just checks that every token is True. Any missing one and it raises Modal artifact finalization received incomplete component tokens: …, listing the components that didn't finish. So it does double duty: it forces remote branches to run, and it holds the local prompt's completion hostage until every one of them actually finished. No outputs, no config - components is the only input, and you'll never set it by hand.

    When you'll actually meet it

    Two realistic encounters. One: you download a workflow someone saved after a remote Modal-Sync run, and there's a stray "Modal Artifact Finalizer" node in it. That's a captured artifact, not authoring source - the README explicitly warns that saved workflows may contain internal proxy/finalizer nodes and should be treated as fixtures. Strip it and rebuild the graph, or just re-mark your nodes. Two: you run into a Dependency cycle detected error after a rewrite; that's the planner's own graph trouble, not the finalizer, and the pack logs proxy-graph diagnostics to comfy.log to help you untangle it.

    Install

    It ships inside the pack, so there's nothing extra to do:

    cd ComfyUI/custom_nodes
    git clone https://github.com/ttulttul/ComfyUI-Modal
    

    Restart ComfyUI, or install "Modal Sync" through ComfyUI Manager's search. No model downloads. The pack is alpha and is itself the whole story here - the finalizer does nothing on its own, so install it only if you actually intend to run nodes through Modal (which needs a Modal account, modal==1.4.2, and COMFY_MODAL_EXECUTION_MODE=remote).

    Bottom line: it's plumbing. Understanding it matters mainly because it's why remote save-only branches work, and because it explains the ghost node in artifacts - not because you'll ever add it to a graph.

    CategoryModal

    Inputs (1)

    NameTypeDefaultDescription
    componentsCOMFY_AUTOGROW_V3

    Outputs (0)

    No outputs