Workflow Resolution¶
Automatically resolve workflow dependencies: custom nodes and models from workflow JSON.
Overview¶
ComfyDock analyzes workflow JSON files to determine what custom nodes and models are needed, then resolves them automatically through:
- Node resolution - Maps node types to installable packages
- Model resolution - Matches model references to your indexed models
- Interactive fixing - Prompts for ambiguous or missing dependencies
- Automatic downloads - Downloads models when sources are available
Resolution happens in two phases:
- Analysis - Parse workflow JSON, extract dependencies
- Resolution - Match nodes to packages, models to files
Both phases are cached for performance.
Automatic resolution¶
Workflows are automatically resolved during cfd commit:
What happens:
- Workflow detection - Finds new/modified workflows
- Dependency extraction - Parses nodes and model references
- Resolution - Matches nodes and models automatically
- Path sync - Updates model paths in workflow JSON
- Commit - Saves resolved state to
.cec/pyproject.toml
If resolution encounters ambiguous or missing dependencies, commit is blocked:
✗ Cannot commit with unresolved issues
Workflow 'portrait-gen' has unresolved dependencies:
• 2 ambiguous nodes
• 1 missing model
Run: cfd workflow resolve portrait-gen
Manual resolution¶
Resolve a specific workflow manually:
Interactive mode (default):
🔧 Resolving dependencies...
⚠️ Node not found in registry: CR_AspectRatioSD15
🔍 Searching for: CR_AspectRatioSD15
Results:
1. comfyui_controlnet_aux (rank #12)
Contains: 12 nodes including aspect ratio tools
2. rgthree-comfy (rank #3)
Contains: 45 nodes including aspect ratio utilities
[1] Select [r] Refine search [m] Manual ID [o] Optional [s] Skip
Choice [1]/r/m/o/s: 1
✓ Resolved CR_AspectRatioSD15 → comfyui_controlnet_aux
⚠️ Model not found: anime-style-xl.safetensors
🔍 Searching model index...
No exact match found.
Similar models:
1. anime-xl-v2.safetensors (confidence: 0.89)
2. anime-style-lora.safetensors (confidence: 0.76)
[1] Select [d] Download URL [o] Optional [s] Skip
Choice [1]/d/o/s: d
Enter download URL: https://civitai.com/api/download/models/123456
Enter target path [loras/anime-style-xl.safetensors]:
✓ Download intent saved
📦 Found 1 missing node pack:
• comfyui_controlnet_aux
Install missing nodes? (Y/n): y
⬇️ Installing nodes...
✓ Installed comfyui_controlnet_aux
📥 Downloading models...
████████████████████████████████████ 2.15 GB / 2.15 GB [100%]
✓ Resolution complete
• 1 node resolved and installed
• 1 model downloaded
Auto mode¶
Skip all prompts and auto-select best matches:
Uses scoring system to pick best candidates:
- Exact matches - Selects automatically
- Fuzzy matches - Picks highest confidence (>0.8)
- No match - Leaves unresolved
- Ambiguous - Picks highest-ranked package from registry
Good for:
- Known workflows from trusted sources
- Batch processing multiple workflows
- CI/CD environments
Resolution phases¶
Phase 1: Node resolution¶
Analyzes each node in the workflow:
Builtin nodes:
Recognized as ComfyUI builtin → No package needed
Custom nodes:
Resolution steps:
- Check pyproject - Previous resolution or manual mapping?
- Check registry - Exact node type match in ComfyUI registry
- Fuzzy search - Embedding-based similarity search
- Interactive prompt - Ask user if ambiguous
Resolution states:
- Resolved - Found package, added to
pyproject.toml - Ambiguous - Multiple candidates found
- Unresolved - Not found anywhere
- Optional - User marked as non-essential
Phase 2: Model resolution¶
Extracts model references from node widgets:
Builtin loaders (exact widget detection):
Widget index 0 contains checkpoint path (from model config).
Custom nodes (pattern matching):
Scans all widgets for .safetensors, .ckpt, .pt extensions.
Resolution strategies:
- Exact hash match - Model filename → BLAKE3 hash in index
- Filename search - Case-insensitive filename lookup
- Previous resolution - Check pyproject for prior download intent
- Fuzzy search - Similarity matching with confidence scores
- Download intent - User provides URL for future download
- Optional - User marks as non-essential
Resolution states:
- Resolved - Found in model index
- Download intent - URL saved, will download on next resolve
- Ambiguous - Multiple models with same/similar filename
- Unresolved - Not found, no download URL
- Optional - User marked as non-essential
Resolution control flags¶
Install missing nodes¶
Automatic installation:
Skips prompt, automatically installs all resolved node packages.
Skip installation:
Only updates pyproject.toml, doesn't install anything. Use when:
- Checking what's needed before installing
- Running in CI without actual installs
- Preparing environment for later installation
Interactive (default):
Prompts after resolution:
📦 Found 3 missing node packs:
• rgthree-comfy
• comfyui_controlnet_aux
• comfyui-impact-pack
Install missing nodes? (Y/n):
Model path synchronization¶
ComfyDock updates workflow JSON to match resolved model paths.
Before resolution:
After resolution:
Path updated to match actual location in model index:
checkpoints/SD XL/sd_xl_base_1.0.safetensors(indexed path)- →
sd_xl_base_1.0.safetensors(workflow path, base directory stripped)
Why this matters:
- ComfyUI frontend expects specific paths in JSON
- Custom nodes may use different base directories
- Path sync ensures workflows load correctly
What gets synced:
- ✅ Builtin nodes only - Safe, known widget structure
- ❌ Custom nodes skipped - Unknown widget layouts, preserved as-is
When sync happens:
- During
cfd workflow resolve(after all resolutions) - During
cfd commit(auto-resolution) - Batch update to avoid cache invalidation issues
Subgraph support¶
ComfyDock fully supports ComfyUI subgraphs (v1.0.7+):
What are subgraphs?
Reusable workflow components introduced in ComfyUI v1.24.3. Group nodes into named subgraphs.
How ComfyDock handles them:
- Flattening - Extracts nodes from subgraph definitions
- Scoped IDs - Preserves node identity (
uuid:3for subgraph nodes) - Filtering - Removes UUID reference nodes (subgraph placeholders)
- Lossless round-trip - Preserves all 14 subgraph fields
- Reconstruction -
to_json()rebuilds original structure
Example workflow with subgraph:
{
"nodes": [
{"id": 10, "type": "0a58ac1f-...", "outputs": [{"type": "IMAGE"}]}
],
"definitions": {
"subgraphs": [{
"id": "0a58ac1f-...",
"name": "Text2Img",
"nodes": [
{"id": 3, "type": "KSampler"},
{"id": 10, "type": "CheckpointLoaderSimple"}
]
}]
}
}
Resolution extracts:
KSampler(builtin, from subgraph)CheckpointLoaderSimple(builtin, from subgraph)- Model reference from checkpoint loader
Subgraph reference node filtered out:
type: "0a58ac1f-..."is a UUID, not a real node type
Resolution caching¶
ComfyDock aggressively caches resolution for performance.
Analysis cache¶
Cached: Workflow dependency parsing (nodes + model references)
Invalidated when:
- Workflow JSON content changes (BLAKE3 hash)
- ComfyUI version changes
- Normalized workflow differs (ignores pan/zoom, revision)
Cache location: SQLite database (.comfydock/cache/workflows.db)
Speed improvement: 50-100x faster on cache hit
Resolution cache¶
Cached: Node/model resolution results
Context-aware invalidation:
- ✅ Workflow content changed - Full invalidation
- ✅ Pyproject modified - Only if relevant sections changed
- ✅ Model index changed - Only if models in workflow affected
- ❌ Unrelated pyproject changes - Cache hit!
- ❌ Unrelated model index changes - Cache hit!
Cache validation:
- Workflow content hash (BLAKE3)
- Pyproject mtime (fast-reject if unchanged)
- Resolution context hash (only workflow-relevant data):
- Custom node mappings for nodes in this workflow
- Declared packages for nodes this workflow uses
- Model entries from pyproject for this workflow
- Model index subset (only models this workflow references)
- ComfyDock version
Manual cache invalidation:
# Force re-resolve by modifying workflow
touch ~/comfydock/environments/my-env/ComfyUI/user/default/workflows/my-workflow.json
Progressive writes¶
Resolution saves changes immediately during interactive mode.
Why this matters:
- Ctrl+C safe - Progress not lost
- Can resume after interruption
- No "all-or-nothing" resolution
What gets written progressively:
- Node resolutions - Added to
[tool.comfydock.workflows.<name>.nodes]immediately - Custom node mappings - Added to
[tool.comfydock.workflows.<name>.custom_node_map]immediately - Model resolutions - Added to
[tool.comfydock.workflows.<name>.models]immediately - Download intents - Saved with pending download URL
- Global model table - Updated when models resolved
Batch operations:
- Model path updates in workflow JSON (all at end)
- Prevents cache invalidation mid-resolution
Download intents¶
Models can be resolved with pending download URLs:
During interactive resolution:
⚠️ Model not found: new-model.safetensors
Enter download URL: https://civitai.com/api/download/models/123456
Enter target path [checkpoints/new-model.safetensors]:
Saved to pyproject:
[[tool.comfydock.workflows.my-workflow.models]]
filename = "new-model.safetensors"
category = "checkpoints"
criticality = "required"
status = "unresolved"
sources = ["https://civitai.com/api/download/models/123456"]
relative_path = "checkpoints/new-model.safetensors"
nodes = [{node_id = "5", node_type = "CheckpointLoaderSimple", widget_index = 0}]
Next resolution:
Detects download intent and downloads automatically:
📥 Downloading models...
████████████████████████████████████ 2.15 GB / 2.15 GB [100%]
✓ Downloaded new-model.safetensors
After download:
- Status changes to
resolved - Hash computed and added
- Sources moved to global model table
- Model indexed
Viewing resolution status¶
Quick check¶
Shows sync state but not resolution details:
Workflows in 'my-env':
✓ Synced (up to date):
📋 portrait-gen
⚠ Modified (changed since last commit):
📝 anime-style
🆕 New (not committed yet):
➕ sdxl-upscale
Detailed status¶
Shows workflows with resolution issues inline:
📋 Workflows:
⚠️ portrait-gen (synced)
2 unresolved nodes
1 missing model
✓ anime-style (modified)
All dependencies resolved
Full resolution report¶
Even in --auto mode, shows what was resolved:
✓ Resolution complete
• 3 nodes resolved
• 2 models resolved (exact hash match)
• 1 model with download intent
Handling unresolved dependencies¶
Unresolved nodes¶
Option 1: Mark as optional
If node isn't essential:
Saved to pyproject:
Option 2: Manual package ID
If you know the correct package:
⚠️ Node not found: MyCustomNode
[m] Manual package ID
Choice: m
Enter package ID: https://github.com/user/ComfyUI-CustomNodes
Option 3: Skip for now
Leave unresolved, fix later:
Commit will be blocked until resolved or marked optional.
Unresolved models¶
Option 1: Provide download URL
⚠️ Model not found: my-model.safetensors
[d] Enter download URL
Choice: d
Enter URL: https://civitai.com/api/download/models/123456
Creates download intent - model will download on next resolve.
Option 2: Mark as optional
Workflow can run without it.
Option 3: Skip
Blocks commit until resolved.
Best practices¶
Recommended
- Resolve before commit - Catch issues early
- Use --auto for trusted workflows - Faster for known-good workflows
- Mark optional nodes/models - Improves sharing compatibility
- Provide download URLs - Helps team members get exact models
- Let commit auto-resolve - Default workflow handles most cases
Avoid
- Committing with --allow-issues - Unresolved deps will break on other machines
- Manual pyproject edits - Use commands for consistency
- Skipping model path sync - Workflows may not load correctly
- Ignoring ambiguous warnings - May resolve to wrong packages
Troubleshooting¶
Resolution fails with cache error¶
Problem: Workflow cache corrupted or stale
Solution: Delete and recreate cache:
Cache rebuilds automatically.
Node resolved to wrong package¶
Problem: Auto-resolution picked incorrect match
Solution: Override with custom mapping:
Edit .cec/pyproject.toml:
Or use manual resolution:
Model path not updating in workflow¶
Problem: Workflow JSON still has old path
Solution: Ensure resolution completes successfully:
- Resolve workflow:
cfd workflow resolve my-workflow - Commit to save:
cfd commit
Path updates happen during resolution, only for builtin nodes.
Download intent not executing¶
Problem: Model has download URL but doesn't download
Solution: Ensure status is "unresolved" with sources:
Should have:
If missing, re-resolve:
Commit blocked with resolved deps¶
Problem: All deps resolved but commit still blocked
Solution: Check for path sync issues:
If shows path sync warning, resolve again:
Next steps¶
- Workflow tracking - How workflows are discovered and managed
- Model importance - Mark models as required/flexible/optional
- Model index - Understanding the model database