ComfyUI and workflow systems
Graphs, custom nodes, dependencies, recipes, debugging and orchestration
- articleWhat do --lowvram, --highvram, --novram and the dynamic VRAM switches mean in ComfyUI v0.42.5, and when does --lowvram do nothing?Problem. Older tutorials describe --lowvram as splitting the UNet; in current builds its meaning depends on DynamicVRAM. Conditions. ComfyUI v0.42.5, NVIDIA or recent AMD ROCm GPU. Method. comfy/cli_args.py: enables_dynamic_vram() is true unless --disable-dynamic-vram, --highvram, --gpu-only, --novram or --cpu is given (--enable-dynamic-vram forces it). main.py enables it only when the GPU is NVIDIA, or AMD with ROCm 7.14 or newer, torch is 2.8+ (2.12+ recommended in the log text) and a working comfy-aimdo is installed; otherwise it logs a warning and falls back to the legacy ModelPatcher. The --lowvram help text states it does nothing when dynamic VRAM is enabled, and otherwise only makes text encoders run on the CPU. Related knobs: --reserve-vram GB, --vram-headroom GB (DynamicVRAM extra headroom), --disable-smart-memory (aggressive offload to RAM), --async-offload, --fast-disk, --cache-ram for RAM thresholds. The vram flags are one mutually exclusive group. Failure modes. Copying...
- articleWhat does ComfyUI-Frame-Interpolation offer (RIFE, FILM, GMFSS...), what frame-count limits apply, and where does it download model weights from?Problem. Raising frame rate of generated clips and knowing what the node pack fetches at run time. Conditions. Fannovel16/ComfyUI-Frame-Interpolation, commit 26545cc2 (pushed 2026-03-29), version 1.0.11, MIT code. Method. VFI nodes (GMFSS Fortuna, IFRNet, IFUnet, M2M, RIFE 4.0-4.9, FILM, Sepconv, AMT, STMFNet, FLAVR, ATM-VFI, MoMo) take an IMAGE batch of at least 2 frames; STMFNet and FLAVR need at least 4 frames (README suggests FILM with multiplier=4 first for short inputs), STMFNet, FLAVR, ATM-VFI and MoMo are 2x only. clear_cache_after_n_frames limits memory. Multiplier values can be scheduled. GPU ops use cupy by default; a taichi backend (set ops_backend in config.yaml) is experimental for non-CUDA devices. Install is via install.py or install.bat (cupy-wheel is installed by the script). Weights: vfi_utils.py tries a list of GitHub release URLs (styler00dollar, the repo's own releases, dajes) and per-file Hugging Face mirror URLs at run time, calling torch.hub download_url_to_...
- articleCan I rely on ComfyUI executing nodes in a particular order, and what do lazy inputs and node expansion change about caching and node IDs?Problem. Workflows with side effects (file writes, counters, API calls) assume top-to-bottom order. Conditions. ComfyUI after PR #2666 (execution is a front-to-back topological sort); docs pages are undated. Method. The Execution Model Inversion Guide says order depends on node IDs and now also on which values are cached, and should be treated as non-deterministic beyond the graph's structure ('Don't rely on the execution order'). Lazy inputs ('lazy': True in INPUT_TYPES plus a check_lazy_status method that returns names of needed inputs) let a node skip evaluating whole upstream branches, so an upstream node may never run; check_lazy_status may be called several times. Node expansion lets a node return a subgraph at runtime (this is how loops work by tail recursion); each expanded node is cached separately, and the docs require expanded node IDs to be unique across the graph and deterministic between executions, including partial executions caused by caching. Execution blocking (Ex...
- articleBeyond a plain prompt object, what does POST /prompt accept in v0.42.5 (prompt_id, front, number, partial_execution_targets, extra_data), and when does a 200 hide dropped outputs?Problem. Headless clients need the full request contract and its silent-success edge cases. Conditions. Local ComfyUI v0.42.5 raw API (docs say this surface has no compatibility guarantee across releases). Method. Body keys read in server.py post_prompt: prompt (required, else 400 no_prompt); client_id (copied into extra_data); extra_data (e.g. extra_pnginfo); number (explicit float priority) or front (true makes the auto number negative so it runs first); prompt_id (optional; must be a canonical lowercase hyphenated UUID or the server returns 400 invalid_prompt_id; absent or null means the server mints a uuid4); partial_execution_targets (list of node ids: only OUTPUT_NODE nodes in the list are run). Response on success: {prompt_id, number, node_errors}. Failure modes. validate_prompt accepts the prompt if at least one output node validates; invalid outputs are logged 'Output will be ignored' and described in node_errors with dependent_outputs, while HTTP stays 200. Only when no ou...
- articleWhat does a ComfyUI-Manager / comfy-cli snapshot actually record, and what must I add (model hashes, disabled nodes, non-registry nodes) to restore an environment faithfully?Problem. Pinning a ComfyUI environment for reproducible reruns or a cloud clone. Conditions. ComfyUI-Manager at commit a74929c6 (2026-10-19), used by cm-cli and by 'comfy node save-snapshot/restore-snapshot' (comfy-cli reference lists the same commands). Method. get_current_snapshot returns five keys: comfyui (git HEAD commit of the ComfyUI folder, only if it has a .git directory), git_custom_nodes (repo URL -> {hash, disabled}), cnr_custom_nodes (registry id -> version), file_custom_nodes (single .py files with disabled flag) and pips (installed pip packages). Packs whose resolved version is not nightly/latest/unknown are recorded by registry id and version; anything else by git URL and commit. Save with save-snapshot --output file.json or .yaml (yaml nests the data under custom_nodes); restore-snapshot looks in ComfyUI-Manager/snapshots if the path is not an existing file and has pip flags --pip-non-url, --pip-non-local-url, --pip-local-url and --restore-to. restore-dependencies r...
- articleWhat does AnimateDiff-Evolved support (context windows, ControlNet, IPAdapter, camera control), where do model files go, and what version of ComfyUI does it require?Problem. Building controllable SD1.5/SDXL animation workflows in ComfyUI. Conditions. Kosinkadink/ComfyUI-AnimateDiff-Evolved, commit 92576512 (pushed 2026-07-28), version 1.6.0, Apache-2.0 code, registry requires-comfyui >=0.3.68, no pip dependencies. Method. Features: sliding context windows (Context Options and View Options) for unlimited length, FreeInit/FreeNoise, motion LoRAs (original ones only work on v2-based modules), scale/effect multival inputs, prompt scheduling (also via FizzNodes), ControlNet/SparseCtrl/IPAdapter, AnimateLCM, CameraCtrl (needs the pruned CameraCtrl file, trained for v3), PIA, HotshotXL and AnimateDiff-SDXL (specific beta_schedule choices; SDXL one still beta), fp8 (requires torch >= 2.1 and changes outputs), and per-frame GLIGEN. Companion packs it names: Advanced-ControlNet, VideoHelperSuite, controlnet_aux, IPAdapter_plus, KJNodes, FizzNodes. Motion modules go in models/animatediff_models and motion LoRAs in models/animatediff_motion_lora, or via ex...
- articleWhat do ComfyUI's Wan2.2 Animate and Fun Camera guides require (custom nodes, model pairs, speed LoRA) and what do they say about the speed/dynamics trade-off?Problem. Reproducing character animation/replacement or preset camera moves with Wan2.2 in ComfyUI. Conditions. docs.comfy.org pages (undated); require a recent ComfyUI (templates ship with it). Method. Animate has two modes: Mix (replace a character in a video with the reference-image character) and Move (animate the reference character with the input video's motion, like Wan2.2 Fun Control). It needs two custom-node packs, ComfyUI-KJNodes and comfyui_controlnet_aux (the DWPose Estimator turns the input video into pose and face control videos), models wan2.2_animate_14B_bf16 or Kijai's fp8-scaled file, clip_vision_h, wan_2.1_vae, umt5_xxl fp8 scaled and an optional LightX2V 4-step LoRA. Fun Camera uses a pair of high-noise and low-noise 14B models (fp8_scaled) plus matching high/low 4-step LoRAs, with preset Pan Up/Down/Left/Right and Zoom In/Out and combinations. The page reports on an RTX 4090D 24GB at 640x640, 81 frames: fp8_scaled about 536 s first run and about 513 s second; w...
- articleWhat is Kijai's ComfyUI-WanVideoWrapper for, when should I prefer native Wan nodes, and what does it pin or change about VRAM?Problem. Choosing between ComfyUI's native Wan support and the wrapper node pack, and avoiding VRAM regressions after updates. Conditions. Repo kijai/ComfyUI-WanVideoWrapper at commit 088128b2 (last push 2026-05-24; not archived), pyproject version 1.4.7, Apache-2.0 code. Method. The README says to use native nodes unless the model or feature is not yet available natively (wrapper is a place to test new models quickly). Install by cloning into custom_nodes and pip-installing requirements.txt (ftfy, accelerate>=1.2.1, einops, diffusers>=0.33.0, peft>=0.17.0, sentencepiece>=0.2.0, protobuf, pyloudnorm, gguf>=0.17.1, opencv-python, scipy). Models: text encoders to models/text_encoders, CLIP vision to clip_vision, transformer to diffusion_models, VAE to vae; fp8-scaled and GGUF variants are named; the wrapper can also use native text-encoder and clip-vision loaders. A noted behaviour change: unmerged LoRA weights are now held as buffers inside blocks, so with block swap the block size g...
- articleHow does comfy-cli / cm-cli work out which custom nodes a workflow needs (deps-in-workflow, install-deps), and what can it get wrong?Problem. Installing the right packs for a downloaded workflow without opening the GUI. Conditions. ComfyUI-Manager commit a74929c6; comfy-cli reference lists deps-in-workflow, install-deps (--workflow accepts .json or .png, --deps a dependency spec, --mode remote|local|cache). Method. extract_nodes_from_workflow loads the workflow JSON (or the 'workflow' text chunk of a PNG), collects every node's 'type' (skipping Reroute, Note and workflow/ group nodes, and expanding extra.groupNodes), then maps node-type names to extension repositories using extension-node-map.json from the chosen channel/mode. Matching order: preemption map, reverse map (first listed extension wins when several provide the name), then nodename_pattern regexes; unmatched names become unknown_nodes. Failure modes. It matches on class names only, so it ignores pack versions or commits recorded elsewhere in the file; a name provided by several packs resolves to the first; nodes not in the map are reported unknown, no...
- articleHow does Comfy API v2 let one client talk to Comfy Cloud, a dedicated deployment and a self-hosted ComfyUI, and what are its poll-first and output-URL rules?Problem. Orchestrating ComfyUI jobs from an application with durable job ids. Conditions. Comfy API v2 as documented 2026-10-23 (changes within v2 additive; breaking changes ship as v3). Method. One contract is served by three surfaces: Comfy Cloud (cloud.comfy.org), per-deployment endpoints (https://{deployment}.run.comfy.app, pinned environment) and open-source ComfyUI through comfy-api-proxy (pip install comfy-api-proxy; proxies 127.0.0.1:8188 and serves v2 on 127.0.0.1:8189; --comfyui and --port change either; --comfyui-base-dir enables uploading model files). Design rules: poll first (GET /api/v2/jobs/{id} is authoritative, SSE is only an enhancement), everything resumable until expires_at, assets content-addressed with a server-computed blake3 hash, follow returned links instead of building URLs. Output.url on a job output is an authenticated content route (401 for a third party); a signed storage URL is the shareable one but short-lived (the docs give about 6 hours on Comfy C...
- articleWhat does comfy-cli's 'comfy run' accept, and does it convert UI-format workflows to API format for me?Problem. Submitting a saved workflow from a terminal without writing HTTP code. Conditions. comfy-cli docs page (undated); latest tag v1.23.0 at fetch (commit a9c5e207). Method. 'comfy run --workflow file.json' accepts both API-format JSON and exported UI-format JSON; the docs state UI workflows are converted to API format client-side. It routes to local or Cloud automatically (signed-in cloud wins unless --where is given), is async by default (returns a prompt_id; 'comfy jobs ls/status/wait/cancel' manage jobs; --wait blocks and 'comfy download' fetches outputs), and the docs advise validating first to catch unknown nodes, missing models and bad wiring. 'comfy launch --background' and 'comfy stop' run a local server; 'comfy install' picks a PyTorch build per GPU vendor. Failure modes. Silent cloud routing when logged in (credits are spent); UI-to-API conversion needs object_info for the target server, so node packs missing there fail. The second failure mode is my inference. Limita...
- articleHow does the Comfy SDK's Idempotency-Key behave on retries (v2 API), and why is a naive retry loop around submit() a double charge?Problem. Retrying a job submission without creating duplicate paid jobs. Conditions. Comfy SDKs (Python comfy_sdk, TypeScript @comfyorg/sdk) against Comfy API v2 (Comfy Cloud, a Comfy API deployment, or self-hosted via comfy-api-proxy). Method. The SDK guide states the v2 contract is reject-on-duplicate, not record-and-replay. Each submit() or run() mints a fresh key unless you pass idempotency_key, so two calls make two jobs and two charges. A reused key fails 422 idempotency_key_reuse (SDK exception IdempotencyKeyReuse); recovery means fetching the job by an id you stored earlier (client.jobs.get). The key is released after a definitive failure (validation error, out-of-credits, queue full) and stays claimed after an ambiguous failure such as a read timeout. Keys expire after 24 hours and must be non-empty printable ASCII. To retry safely persist both the key and the job id across attempts, and persist the id before doing anything else. The guide notes Comfy Router's key behaves d...
- articleWhat flag set runs ComfyUI as a locked-down headless API server (listen address, TLS, upload size, no custom nodes, offline), and what does the project say about authentication?Problem. Exposing a GPU box as an API without enlarging the attack surface. Conditions. ComfyUI v0.42.5 CLI; docs.comfy.org self-hosting and startup-flag pages. Method. Defaults: --listen 127.0.0.1 (bare --listen means 0.0.0.0,::; a comma-separated list is accepted), --port 8188, --max-upload-size 100 MB. Relevant flags in cli_args.py: --tls-keyfile and --tls-certfile (TLS needs both), --enable-cors-header [ORIGIN] (bare means '*'), --disable-auto-launch, --disable-all-custom-nodes with --whitelist-custom-nodes, --offline (restrictive Content-Security-Policy for the frontend, also disables partner nodes), --disable-partner-nodes, --multi-user, --enable-manager (Manager is opt-in), --base-directory, --input-directory and --output-directory, --user-directory, --temp-directory, --disable-metadata. The self-hosting page states the server has no authentication by default and says to bind non-loopback addresses only on trusted networks or behind an authenticating reverse proxy; community ...
- articleHow do I chain Wan 2.2 image-to-video clips by extracting the last frame without quality loss, and when does ComfyUI rerun only the extraction step?Problem. Making videos longer than one generation by seeding each segment with the previous segment's final frame. Conditions. Example workflow doc in radiatingreverberations/comfyui-workflows (MIT; repo last pushed 2025-08-08; fetched from main, no commit pin), needs ComfyUI-VideoHelperSuite. Method. Take the last frame straight after VAE Decode via a Select Images node: set indexes to all frames but the last for the video file, and the last frame alone for a lossless image saved separately; the last frame is excluded from the video to avoid duplication when the next clip starts from it. Keep frames lossless and compress only at the final concatenation (the page shows ImageMagick piping into ffmpeg libx264 crf 18 at 16 fps). To end earlier than the last frame, change the indexes and rerun; the page says that as long as nothing else changed ComfyUI reruns only the extraction part, and this needs a fixed seed. Load the chosen frame with Load Image (from Outputs) and refresh, then cha...
- articleWhat does the official workflow JSON schema say about embedding model references and hashes, and when does a saved PNG carry the workflow versus only the API prompt?Problem. Recording enough in a file to rerun a ComfyUI result. Conditions. Workflow schema v1 (latest) as published on docs.comfy.org; ComfyUI v0.42.5 SaveImage. Method. The published schema's ComfyWorkflow1_0 requires version, state and nodes, allows extra top-level properties, and defines an optional top-level 'models' array whose entries have name, url and directory as required fields and optional hash and hash_type (a free string, additionalProperties false). Nodes carry mode, inputs, properties (including 'Node name for S&R') and widgets_values (array or object). So an exporter can put model download URLs plus hash/hash_type into the workflow file; nothing in the schema forces a hash. SaveImage always writes the API prompt into PNG text chunk 'prompt' (unless --disable-metadata) and writes the extra_pnginfo entries (normally 'workflow') only if the client sent extra_data.extra_pnginfo. Inference: images produced through a bare API submit contain the API prompt but no UI workflo...
- articleWhat does the Comfy Registry require in pyproject.toml for a custom node (name, semver, requires-comfyui, frontend pin), and what gets packaged on publish?Problem. Authors and auditors need to know what version metadata a published node carries and what is in the archive. Conditions. docs.comfy.org registry pages fetched 2026-10-23 (undated). Method. [project] name is required, immutable after creation, under 100 characters, alphanumerics plus -, _ and ., case-insensitive; version is required semantic versioning X.Y.Z; license, description, requires-python and classifiers (OS and GPU accelerator) are optional/recommended; repository URL required. Compatibility pins: dependencies may include comfyui-frontend-package ranges, and [tool.comfy] requires-comfyui accepts PEP-440-style operators and ranges (the docs list <, >, <=, >=, ~=, <>, != and ranges). [tool.comfy] PublisherId is required and immutable; includes force-adds git-ignored build folders. 'comfy node publish' packages every git-tracked file; a .comfyignore (gitignore syntax) removes tracked files; publishing uses a per-publisher API key, or a GITHUB secret named REGISTRY_ACCE...
- articlebpy 5.2.2 on PyPI requires Python ==3.13.* and declares licence 'GPL-3.0' with author Blender Foundation; the 5.2 API docs say the module is not on the official download page but a pre-compiled module is available via PIP; blender.org describes Blender as...Corrected 2026-10-23 - see C3-B684-05; the original statements below are kept for history and are superseded where the correction says so. bpy 5.2.2 on PyPI requires Python ==3.13.* and declares licence 'GPL-3.0' with author Blender Foundation; the 5.2 API docs say the module is not on the official download page but a pre-compiled module is available via PIP; blender.org describes Blender as GPL-licensed.
- articleThe Blender 5.2 manual's EEVEE limitations page says headless rendering is not supported on headless Windows systems and says nothing about Linux or macOS headless rendering on that...Corrected 2026-10-23 - see C3-B684-05; the original statements below are kept for history and are superseded where the correction says so. The Blender 5.2 manual's EEVEE limitations page says headless rendering is not supported on headless Windows systems and says nothing about Linux or macOS headless rendering on that line.
- articleDoes an image's position and the batch size change which image I get for a given seed (ComfyUI and diffusers), and how do I regenerate one image from a batch on its own?Corrected 2026-10-23 - see C3-B681-09; the original statements below are kept for history and are superseded where the correction says so. In ComfyUI the default KSampler path (a latent with no batch_index) draws noise for the whole batch in one call, while a latent that carries batch_index gets noise per index, so a picked-out image can be regenerated from its index; LatentBatchSeedBehavior 'fixed' (the node default) gives every batch item the same index and so the same starting noise. Diffusers does the same split with a single generator (one draw for the batch) versus a list of generators (one draw per image). Separately from RNG, a 2023 diffusers thread reports that batch size changed the image on three GPUs even with equal seeds, and a maintainer attributed this to different CUDA kernels per batch size (a claim); the reporter's workaround was to regenerate the wanted image at batch size 1 with deterministic flags.
- articleBlender 5.2 documents --python-exit-code (0..255, zero disables), so CI must pass a non-zero code to fail on Python exceptions; the v5.2.2 source defines --python-use-user-env, which the 5.2 manual argument page does not...Corrected 2026-10-23 - see C3-B684-05; the original statements below are kept for history and are superseded where the correction says so. Blender 5.2 documents --python-exit-code (0..255, zero disables), so CI must pass a non-zero code to fail on Python exceptions; the v5.2.2 source defines --python-use-user-env, which the 5.2 manual argument page does not list.
- articleWhat would a regression gate for a ComfyUI workflow change look like, and which parts are documented versus my own design?Problem: a workflow edit (new node, changed sampler, swapped model) can silently change output or break on another machine. Conditions: you can run a ComfyUI server (CPU or GPU) in CI and keep a baseline output set. Method (INFERENCE, assembled from documented parts): (1) static portability layer: compare the workflow's node types and recorded version fields with the target install (see C3-B590-04..06). (2) start-up layer: launch with the node pack installed and fail on import errors, as in ComfyUI's launch smoke test. (3) execution layer: submit the API-format graph with comfy run --wait --timeout and require exit 0 and expected output files, which is all Comfy's GPU CI checks. (4) quality layer: fixed seed, baseline directory and image-similarity threshold as described in C3-B579-13; keep it on the same hardware and software pins as the baseline because the repo provides no cross-device guarantee. (5) drift layer: scheduled re-check of pins. (6) release layer: publish only after l...
- articleHow should headless CI wait for a ComfyUI workflow and what exit-code traps does comfy-cli document?Problem: scripting comfy-cli in CI and getting trustworthy exit codes. Conditions: comfy-cli at commit 0b49c62. Method: its own e2e test starts ComfyUI with comfy launch --background (CPU by default) and runs comfy run --workflow <file> --wait --timeout 180. The README says comfy run submits asynchronously and prints a prompt_id unless --wait is given. comfy update all exits 0 even when the custom-node update fails unless --exit-on-fail is passed, and even with it, cm-cli handling a single failing pack prints ERROR but exits 0, so that case is invisible to the exit code. comfy run --prompt without --workflow uses a bundled graph needing the SD1.5 checkpoint, which comfy-cli does not download. Failure modes: a green CI step after a partial custom-node update; forgetting --wait and testing before the job finishes. Limitations: README and tests read, nothing executed; extends rather than repeats C3-B574-20 on run arguments. Version/date: 0b49c62, 2026-10-23.
- articleHow can a ComfyUI-related repo detect that an upstream rendering or format assumption drifted, without making every pull request depend on the network?Problem: workflows and tooling depend on constants owned by another repository (here ComfyUI_frontend geometry). Conditions: comfy-cli at commit 0b49c62, .github/workflows/litegraph-parity.yml. Method: the job runs weekly (cron Mondays), on PRs touching the layout model, and on demand with an optional frontend ref. It first runs offline parser unit tests, then a script comparing constants with upstream under continue-on-error, then a Report step that treats exit 0 (match), exit 1 (drift) and exit 2 (could not read upstream) differently. The authors state the schedule is deliberate: the changing input is upstream, not the PR diff. Transfer (inference): for a workflow-regression gate, run a scheduled job that re-checks pins that live elsewhere (required node versions, frontend package, model hashes) and keep 'could not check' distinct from 'drifted'. Failure modes: collapsing network errors into failures trains people to ignore the job. Limitations: the specific parity script was not ...
- articleWhat does `comfy node validate` (run before `comfy node publish`) actually check?Problem: assuming comfy node validate protects users from broken or unsafe nodes. Conditions: Comfy-Org/comfy-cli at commit 0b49c62, comfy_cli/command/custom_nodes/command.py. Method: validate_node_for_publishing extracts the node configuration from pyproject.toml, exits 1 if configuration cannot be read or project.version is empty, then runs ruff check . -q --select S102,S307,E702 --exit-zero. S102 is exec use, S307 is eval use, E702 is multiple statements on one line. --exit-zero means findings print as warnings and never fail the command; the code prints that exec/eval will soon become errors. The code only handles FileNotFoundError for a missing ruff; inference: a missing ruff module under python -m would give empty stdout and still print the passed message. comfy node publish calls the same function, then requests a signed upload URL and uploads a zip of the directory respecting .gitignore. So the gate is configuration plus three lint rules (warn-only); it does not import the n...
- articleWhat does the Comfy publish-node-action do, and what should I add before letting it publish a custom node?Problem: automating Comfy Registry publishing from GitHub. Conditions: Comfy-Org/publish-node-action main at commit d2366e7 (2025-05-10 per the commits feed). Method: the README workflow triggers on push to main touching pyproject.toml (plus workflow_dispatch) and calls Comfy-Org/publish-node-action@main with the token from the REGISTRY_ACCESS_TOKEN secret. The composite action checks out, sets up Python 3.10, runs pip install comfy-cli with no version pin, then comfy node publish --token <input>. The README says comfy-cli publishes the version in pyproject.toml, so the version must be bumped by hand. Inference: nothing in the action runs tests or workflow checks before publishing, and unpinned @main plus unpinned comfy-cli means the publish step can change without a change in your repo; the token is passed as a command argument, which GitHub masks in logs but which is visible in the process list on the runner. Method for a safer gate (inference): add a prior job running your tests ...
- articleWhat does ComfyUI's launch smoke test check, and how can it be adapted to catch custom-node import failures?Problem: a custom node that raises at import can break the whole ComfyUI start-up. Conditions: ComfyUI commit fb3befd, test-launch.yml. Method: the job installs CPU torch and requirements, starts python main.py --cpu with output tee'd to console_output.log in the background, waits for 127.0.0.1:8188 for 30 seconds with wait-for-it, filters two known triton warnings, then fails if the log matches the regex 'Exception|Error'. The log is uploaded as an artifact kept 30 days. Inference for custom nodes: place the node pack under custom_nodes before the start and reuse the same grep; look for the start-up import-failure line (not quoted here). Failure modes: any benign log line containing 'Error' fails the job, so the filter list grows; a node that fails silently without that word passes; 30 s may be too short for large packs on cold caches. Limitations: not executed. Version/date: fb3befd, 2026-10-23.
- articleHow does ComfyUI's tests/execution harness start a server and test graphs, and can I reuse the pattern for a custom node pack?Problem: automated tests for node behaviour (caching, validation errors, missing nodes) rather than image quality. Conditions: ComfyUI commit fb3befd, tests/execution/test_execution.py (over 1,300 lines). Method: a class-scoped pytest fixture starts python main.py as a subprocess with --output-directory, --listen, --port, --extra-model-paths-config tests/execution/extra_model_paths.yaml and --cpu, parametrised over four modes (--cache-classic, --cache-lru 100, --cache-none, and default with assets enabled). A websocket client then submits graphs built with GraphBuilder from comfy_execution.graph_utils, including nodes from tests/execution/testing_nodes/testing-pack, and asserts on outputs and errors (e.g. test_missing_node_error submits a graph with a removed node and checks the server survives). conftest.py adds --skip-timing-checks for variable CI machines. Inference: a custom-node author can copy the fixture, point custom nodes at a test pack and parametrise cache modes; nothing ...
- articleHow does the Comfy GPU CI (comfy-action) decide a workflow run passed, and when does it run?Problem: understanding what Comfy's own GPU workflow test proves. Conditions: Comfy-Org/comfy-action at commit 2239a58 (last commit 2025-04-18 per the commits feed) and the ComfyUI workflows that call it. Method: action.py runs, per workflow JSON, the command comfy run --workflow <file> with a 600 second timeout under subprocess check=True. It then looks for output filenames in the CLI output; if none are found and the default ComfyUI_00001_.png is absent it raises 'no outputs found'. It uploads outputs to a GCS bucket and posts status Completed or Failed to a results API. So pass means exit code 0 plus at least one output file; no baseline image, hash or score is compared (inference from reading action.py). Trigger facts: ComfyUI's test-ci.yml has its push trigger commented out and only workflow_dispatch active; the pull-request variant runs when the label Run-CI-Test is added; both call comfy-org/comfy-action@main (unpinned) on self-hosted runners and need a GCS secret for the das...
- articleDoes ComfyUI's CI run the inference and image-quality (SSIM) regression tests?Problem: C3-B579-13 describes tests/inference and the quality comparison; whether CI exercises them is a separate question. Conditions: ComfyUI commit fb3befd. Method: tests/README.md documents the baseline flow (pytest tests/inference --output_dir tests/inference/baseline, edit, then run pytest). tests/conftest.py forces test_quality to run last. I fetched 26 of the 29 workflow files from the same tree and searched them for pytest, tests/inference and test_quality: only tests-unit and tests/execution appear; tests/inference and the quality comparison are not invoked by any of them (three windows_*release_dependencies* files were not read). Inference: the SSIM regression is a manual local workflow, not an automated gate in this repo. The GPU CI (comfy-action) compares nothing pixel-wise (see sibling finding). Failure modes: assuming ComfyUI core changes are SSIM-checked in CI. Limitations: negative result from a text search; other repositories (Comfy-Org CI containers) were not sear...
- articleWhich tests does the ComfyUI repository actually run automatically, and do those jobs block a merge?Problem: knowing what ComfyUI's own CI proves before copying it for a custom-node pack. Conditions: Comfy-Org/ComfyUI at commit fb3befd. Method: the .github/workflows files at that commit define (a) Unit Tests, python -m pytest tests-unit on ubuntu, windows, macos and ubuntu-arm with CPU torch; (b) Execution Tests, python -m pytest tests/execution -v --skip-timing-checks on four OSes; (c) a launch smoke test, (d) Build package (requirements install on Python 3.10-3.14), and (e) Ruff plus Pylint on comfy_api_nodes. Both the unit and the execution jobs set continue-on-error: true. Inference: with that setting a failing matrix leg does not fail the job, so these jobs are advisory unless the repository's branch rules require something else; branch protection settings were not visible to me. Failure modes: copying the file and assuming red means blocked. Limitations: only workflow YAML read. Version/date: fb3befd, read 2026-10-23.
- articleWhen a workflow uses a node that is deprecated, renamed or missing on the target ComfyUI, what does the server and frontend do, and how can I pre-check?Problem. Moving a workflow between versions can silently swap in deprecated nodes or leave red placeholder nodes. Conditions. ComfyUI 9fe7ef76 (server.py, nodes.py) and frontend 174bd880 (app.ts). Method. Server side: any node class with DEPRECATED = True is reported with 'deprecated': true in the node info (likewise 'experimental' and 'dev_only'); core examples are CheckpointLoader (display name 'Load Checkpoint With Config (DEPRECATED)') and ImageBatch ('Batch Images (DEPRECATED)'). Frontend side: while loading a graph it builds a missingNodeTypes list, skips nodes that are muted or bypassed, records the pack id (cnr_id) when present, and marks an entry replaceable when its node-replacement store has a replacement. Pre-flight (inference, built from those behaviours): fetch /object_info from the target server; for every node type in the workflow JSON, check it exists and read its deprecated flag; list types that exist only in disabled or non-registry packs using properties.cnr_id/a...
- articleWhat does ComfyUI-qwenmultiangle output for camera control, what must be installed with it, and what language caveat does it state?Problem. Control camera azimuth, elevation and distance in an image-edit model through ComfyUI without hand-typing camera phrases. Conditions. jtydhr88/ComfyUI-qwenmultiangle at commit bf8d032a (MIT, copyright 2026 Terry Jia). The node is an interactive Three.js viewport that only builds a prompt string; it generates nothing itself and works with a separate Qwen-Image-Edit-2511 multiple-angles LoRA. Method. (1) Clone the repo into custom_nodes and restart. (2) Download the LoRA named in the README from its Hugging Face page into the lora folder (its licence was not read). (3) Add 'Qwen Multiangle Camera' (image/multiangle); set horizontal angle 0-360 degrees, vertical angle -30 to 60 degrees and zoom 0-10 by handles, sliders or dropdowns. (4) The output prompt has the form <sks> {azimuth} {elevation} {distance}, using fixed vocabulary: eight azimuth terms (front view ... front-left quarter view), four elevation terms (low-angle shot -30, eye-level shot 0, elevated shot 30, high-angl...
- articleIs Masquerade Nodes still worth installing for mask-driven inpainting, and what do its mask-to-region and cut/paste nodes do?Problem. Decide whether to depend on an old mask utility pack. Conditions. badcafecode/Masquerade-Nodes-ComfyUI commit 432cb4d1, last commit 2024-06-19, MIT (copyright 2023 Jacob Segal); no requirements.txt at that commit (404). Examples use SD1.5 and SD1.5-inpainting. Method. The maintainer's README opens with a recommendation to use Impact Pack instead unless a dependency-free library is needed, so treat Masquerade as legacy. What it offers: 'Mask By Text' (ClipSeg text-prompted masks, '|' separated prompts, precision and normalise controls, raw 0-1 ClipSeg output); mask morphology (dilate, erode, open, close); combine/unary/blur/mix operations; 'Mask To Region' (padding, keep_ratio / multiple_of constraints, min size, batch behaviour) to pick a sensible crop around a mask for full-resolution inpainting; 'Cut By Mask' and 'Paste By Mask' (resize behaviours) to cut the region out and paste the result back; plus colour-space, QR, rectangle and incrementer helpers. For a maintained a...
- articleWhich workflow settings multiply or divide GPU cost per job in ComfyUI: CFG 1, regional sampling, recovery samplers, cached partial re-runs?Problem. Two workflows with the same steps and resolution can differ by a large factor in model evaluations. Conditions. ComfyUI core samplers.py at 9fe7ef76; Impact Pack Regional Sampler tutorial (default-branch text, no commit id); a Wan 2.2 end-frame example. Levers. (1) CFG 1.0: in the sampler, when cond_scale is close to 1.0 (and disable_cfg1_optimization is not set) the unconditional branch is dropped, so each step evaluates the model once instead of twice (inference: count of passes; see C3-B582-05 for why negatives then do nothing). (2) Regional Sampler: a base-only stage runs base_only_steps, then each step does base-region sampling plus one sampling per region, and the tutorial states that the optional additional_mode recovery 'requires a longer time for sampling because a second sampling is performed at each step in each region'. A rough model (inference): passes per step = 1 + R (+ R with recovery) for R regions, so budget about (1+R) to (1+2R) times a single-sampler ste...
- articleWhat does Yedp Action Director produce for ControlNet workflows, how does it store scene state, and what must move with a workflow to another machine?Problem. Drive pose, depth and edge control from posed 3D characters rather than from extracted video, and keep the setup portable. Conditions. yedp123/ComfyUI-Yedp-Action-Director at commit 73420247 (MIT, 2026), README of version V9.3; author-made. Method. The node embeds a Three.js viewport; characters are loaded from .fbx/.glb/.bvh, animations are sequenced with crossfades, cameras are keyframed or imported from FBX, and one bake yields seven batches: pose (OpenPose colours), depth, canny-style rim light, normal, shaded, alpha matte and textured. Depth near/far are set manually. A companion Mocap Surgeon extracts and cleans motion from video (MediaPipe pose/hands/face, 1-euro filtering) and bakes .glb clips; a Blockout node builds simple scenes. Portability. Scene state (cameras, keyframes, characters, environments, lights, mocap bindings) is serialised inside the standard ComfyUI workflow .json, but assets are looked up by name in ComfyUI/input/yedp_anims, yedp_envs, yedp_cams a...
- articleWhat does Houdini PDG/TOPs give a procedural content pipeline that a plain node network does not (work items, dependencies, minimal recook)?Problem. Generating many world variants (wedges) or batch-baking assets is slow and hard to repeat when done by hand. Conditions. Houdini TOPs network. Method. TOP nodes generate work items (for example one per animation frame) and store data in attributes; dependencies between items are explicit so independent items run in parallel on one machine or a farm, and when an input changes TOPs recook only dependent items. Inference (mine): treat each seed/parameter set as a work item attribute so each variant is a logged, re-runnable task; this fits batching AI asset generation or validation steps as items. Failure modes. Not covered on this page: caching behaviour on disk, non-deterministic external tools. Limitations. Introduction page only. Date. 2026-10-23.
- articleI have an image made in A1111/Forge or diffusers with a seed; why does the same seed and prompt in ComfyUI (or the reverse) give a different image, and which differences are known?Corrected 2026-10-23 - see C3-B681-05; the original statements below are kept for history and are superseded where the correction says so. Different UIs and libraries use different noise sources, schedulers, prompt-weight handling and extensions, so a seed is not portable between them. The ComfyUI FAQ and A1111's option text both say the noise source differs (CPU in ComfyUI, GPU by default in A1111, with a CPU option). In two public threads users could not match results across tools: a ComfyUI-vs-Forge thread where a mismatched scheduler (Karras vs normal) explained one artefact and a commenter said exact cross-UI recreation is 'frankly impossible', and a diffusers-vs-ComfyUI Qwen-Image-Edit thread where several causes were proposed (output size, RoPE alignment, prompt template, sigma shift) and none was confirmed in the thread. Treat seed + prompt as non-portable and compare like with like.
- articleIn the diffusers-vs-ComfyUI Qwen-Image-Edit thread, did anyone identify a practical cause of the quality gap?Problem. C3-B060-G23-07 says several causes were proposed and 'none was confirmed in the thread'. Correction type: (c) missing an important limitation/finding. Method. A contributor (linoytsaban) tested the same script with and without height=1024,width=1024 and reported that omitting them matched ComfyUI quality; a Qwen maintainer (naykun) then advised against custom output height and width and called that likely the main reason. The reporter later disputed that this explains everything, and other hypotheses (RoPE text-frequency base, prompt template, sigma shift) stayed unresolved. Practical rule: for Qwen-Image-Edit in diffusers, let the pipeline compute the output size and keep conditioning images matched to it. Limitations. No maintainer confirmed that the size effect fully closes the gap. Version and date. Thread state as fetched 2026-10-23.
- articleWhat tasks does Wan VACE cover (reference-to-video, video editing, masked editing, expand), what inputs does it take, and which base-model licences apply?Problem. One toolchain for video control tasks that otherwise need separate models. Conditions. VACE built on Wan2.1 (1.3B at about 81x480x832, 14B at about 81x720x1280) and LTX-Video 0.9. Method. VACE takes a text prompt plus optional video, mask and reference images; tasks include reference-to-video (R2V), video-to-video (V2V) and masked video-to-video (MV2V), which the README markets as Move-Anything, Swap-Anything, Reference-Anything, Expand-Anything and Animate-Anything. Run through vace_pipeline.py with a preprocessor task name, e.g. --task depth for V2V depth control or --task inpainting --mode bbox --bbox x1,y1,x2,y2 for masked editing; or preprocess into src_video, src_mask, src_ref_images and call vace_wan_inference.py. Prompt extension is needed for LTX-Video and English-language Wan2.1 to unlock full performance, but in editing tasks check the expanded text still matches the unseen input video. Failure modes. The README warns prompt extension may not match the video bein...
- articleWhat exactly goes into ComfyUI's output-cache key for a node, so I can predict whether editing one widget re-runs a node (input signature plus all ancestors, not node IDs)?Problem. Agents that edit an API-format prompt and resubmit need to predict which nodes re-execute. Conditions. ComfyUI v0.42.5 (tag, commit 483dae43), any cache mode except --cache-none; the output cache is built with CacheKeySetInputSignature in comfy_execution/caching.py. Method. For each node, get_node_signature builds a list from the node itself plus every ancestor (get_ordered_ancestry). Each immediate signature is [class_type, IS_CHANGED/fingerprint value] plus, only when the class sets NOT_IDEMPOTENT or declares a UNIQUE_ID hidden input, the node ID; then every input key in sorted order: literal widget values are included verbatim, linked inputs are replaced by ('ANCESTOR', ancestor_order_index, socket). The list goes through to_hashable. Consequences: (a) changing any literal upstream changes the key of every downstream node; (b) node IDs are not part of the key for ordinary nodes, so two identical sub-graphs with different IDs share one cache entry and renumbering nodes do...
- articleWhich cache classes does ComfyUI construct for each --cache-* flag, what is the separate 'objects' cache, and how do I clear cached node results on a running server?Problem. Memory growth or stale-looking reruns on a server; choosing a cache flag. Conditions. ComfyUI v0.42.5. Method. main.py prompt_worker maps flags to execution.CacheType: default RAM_PRESSURE; --cache-classic (and --high-ram, which cli_args rewrites to classic) CLASSIC; --cache-lru N (N>0) LRU; --cache-none NONE. The flags live in one mutually exclusive argparse group. CacheSet creates two caches: 'outputs' (HierarchicalCache / LRUCache / RAMPressureCache keyed by input signature) and 'objects' (HierarchicalCache keyed by node id and class type, holding node instances); NONE replaces both with NullCache. --cache-ram takes at most two GB values (active-cache threshold, then inactive/pin threshold) and defaults to 10% of RAM clamped to 2-10 GB active. Runtime reset: POST /free with {"free_memory": true} sets a queue flag; the worker thread then calls e.reset(), building a fresh CacheSet; {"unload_models": true} only unloads models. Failure modes. /free only sets flags and return...
- articleIf I overwrite a checkpoint or LoRA file in place under the same filename, will ComfyUI's cache notice? Which core nodes hash file contents in IS_CHANGED?Problem. A long-lived headless server may keep serving cached results after a model file is replaced under the same name. Conditions. ComfyUI v0.42.5, default RAM-pressure or any non-null cache, same server process. Method. In nodes.py only three IS_CHANGED definitions exist (LoadLatent, LoadImage, and the channel-based LoadImageMask delegating to LoadImage); the first two hash the file with sha256. CheckpointLoaderSimple has no IS_CHANGED and its only input is the ckpt_name string chosen from folder_paths.get_filename_list. From the cache-key code (previous finding) the node signature therefore contains just the filename. Inference: replacing the file's bytes without renaming does not change the key, so a still-cached loader (and anything downstream) can be reused; use new filenames per version, or restart the server, or POST /free with free_memory true to reset the executor caches (main.py prompt_worker calls e.reset()). Failure modes. Provenance logs that record only the filename...
- articleHow do IS_CHANGED and fingerprint_inputs really work in ComfyUI: what do they receive, when are they evaluated, what happens if they raise, and where do the docs differ from the code?Problem. Custom-node authors and agents rely on IS_CHANGED to force or avoid re-execution. Conditions. ComfyUI v0.42.5; class-level IS_CHANGED (V1 nodes) or fingerprint_inputs (V3 nodes). Method. IsChangedCache.get in execution.py looks first for a V3 'fingerprint_inputs' override, else an IS_CHANGED attribute; if neither exists the value is False. It is called with get_input_data(node inputs, ..., None), i.e. only literal widget values: the code comment says outputs of upstream nodes are intentionally not used, so linked inputs are not available to IS_CHANGED. The result list is stored on the node dict (computed once per prompt) and enters the cache signature. Return a stable content hash (the built-in LoadImage returns a sha256 of the file) to invalidate on content change; return float('nan') to force re-execution every run. Failure modes. If IS_CHANGED raises, the code logs a warning and stores NaN, which silently forces re-execution every time. Returning True/False is a trap bec...
- articleWhich documented diffusers mechanisms reduce temporal flicker in AnimateDiff-style video (video-to-video strength, FreeInit, FreeNoise), and what do they cost?Problem. Frame-to-frame flicker and drift in diffusion video. Conditions. diffusers AnimateDiff pipelines (SD 1.5 class). Method. (1) Video-to-video: AnimateDiffVideoToVideoPipeline takes video, prompt, guidance_scale, num_inference_steps and strength; the doc examples use strength=0.5 and, with ControlNet conditioning frames, strength=0.8 with controlnet_conditioning_scale=0.75 and 10 steps at guidance_scale=2.0. Inference (not stated in the doc): lower strength keeps more of the source video's frames and therefore its motion and stability. (2) FreeInit: refines the initial noise iteratively to improve temporal consistency without training; enable with pipe.enable_free_init(method='butterworth', use_fast_sampling=True) and disable with pipe.disable_free_init(). It costs extra sampling passes (num_iters). (3) FreeNoise: noise rescheduling, temporal attention over sliding windows and weighted averaging of latent frames to generate longer videos from short-video models, with enable_fr...
- articleWhat must an agent record alongside a ComfyUI workflow so it can be re-run faithfully later?The two JSON forms leave out most of what decides the output. From the pinned frontend schema and graphToPrompt, an archive should hold the executed API prompt (resolved seeds, bypass applied) and the editor workflow, and then add items neither file can hold: the ComfyUI server revision, the content hash of every model file named only by file name, node-pack versions where the pack omitted them, the content hashes of loaded input files, the seed policy, and the software/hardware stack. The frontend version and optional node-pack versions are recorded inside the workflow; the backend version and model hashes are not (schema-derived; model hashes are optional declarations).
- articleHow does Godot decide that an imported asset in .godot/imported is stale and must be reimported?Godot (code at 6790667) uses a cheap mtime test (source and .import, plus missing imported files when the reimport_missing_imported_files setting is on), then a deep test: changed .import md5, missing importer, newer importer format version, invalid settings, missing .md5, moved source, or changed source or destination md5 all trigger reimport. A touched but byte-identical source passes to the md5 test (mtime is an optimisation). The docs describe only the source-md5 trigger and erased .godot/imported files, and recommend not committing .godot/.
- articleWhat generation metadata is lost when a generated image is re-encoded, converted or uploaded, and how should an agent preserve it?Partially verified: the curator re-read none of the cited sources; S8, S9, S2, S1, S4, S3 rest on the producer's pinned reading. Embedded settings live in ancillary PNG text chunks (or EXIF/tags) that decoders ignore, so they exist only while a PNG-aware tool copies them. The PNG specification says ordinary image editors usually discard unrecognized information; the tools' own code writes nothing when their disable switches are set and writes different containers per format. Practical rule (synthesis): extract and store the metadata together with a hash of the original bytes before any resize, convert, screenshot or upload, because the sources inspected give no way to recover it afterwards. Behaviour of specific hosting sites was not verified.
- articleHow can I tell a ComfyUI workflow (UI/graph) JSON from an API-format prompt JSON, and what differs in ids, links, widget values and version fields?Corrected 2026-10-23 - see C3-B595-07; the original statements below are kept for history and are superseded where the correction says so. At the inspected commits the two formats are cleanly distinguishable by top-level shape. A workflow (editor) JSON is an object with a 'nodes' array, 'links', a numeric 'version' (0.4-style or 1) and layout data; an API prompt is a flat map from node id to {class_type, inputs, _meta} where a link is a two-element array [source node id, output index] and widgets are plain named inputs. The API form is derived at queue time from the workflow (muted/bypassed nodes omitted, UI-only widgets dropped) and has no version field; the official docs table for the save format has a row ('Node keys') that does not match the schema.
- articleWhich model file formats can run code when loaded in ComfyUI, and what protections exist at the pinned versions?Corrected 2026-10-23 - see C3-B595-06; the original statements below are kept for history and are superseded where the correction says so. Pickle-based model files (.ckpt, .pt, .pth, .bin) can execute code when loaded, according to Hugging Face's documentation; safetensors is designed not to. ComfyUI at commit 46aad33e loads .safetensors/.sft files with safetensors.safe_open and everything else with torch.load(..., weights_only=True), which PyTorch documents as narrowing, not eliminating, remote-code-execution risk (denial of service and memory corruption may still be possible). ComfyUI-Manager's install_model path requires the 'middle' security level and a whitelist match against model-list.json, and for non-.safetensors filenames without 'high' permission it also requires a default-channel URL match. The ComfyUI frontend's missing-model download allowlist (huggingface.co, civitai.com and civitai.red prefixes plus a few exact URLs) still permits .ckpt, .pt and .pth suffixes. Huggin...
- articleDo the cited frontend sources show the 'Node keys' docs-table mismatch and the muted/bypassed omission in the API form? Correction: the cited docs file is about widget serialization and contains neither; those statements need other sources.Problem. The earlier finding says an official docs table row ('Node keys') does not match the schema and that the API form omits muted/bypassed nodes. The cited docs/WIDGET_SERIALIZATION.md (commit 5306a54b) is a note on two 'serialize' properties with a permutation table; it has no 'Node keys' row and does not mention muted or bypassed nodes. What the cited file does support. widget.serialize controls what is written to widgets_values in the workflow JSON; widget.options.serialize controls what is sent in the API prompt; the two correspond to the WORKFLOW and PROMPT tags embedded in output files. The schema ranges cited show version as a number and node properties cnr_id/aux_id/ver/models. Impact. The top-level distinguishing shape (nodes array and numeric version vs flat id-to-{class_type, inputs}) remains supported by the schema; the two extra claims should be re-sourced (the docs.comfy.org page and graphToPrompt source were not cited and were not checked here). Limitations. Abse...