- name
- comfy-debug
- description
- Debugging skill for the comfy CLI — failed workflows, stuck jobs, error envelopes, and the fastest path from "it broke" to "fixed".
When something fails on the comfy CLI, **read the JSON envelope first**, act on the `hint`, and only go deeper if needed. This skill is the bottom-up playbook.
## The envelope is the source of truth
Every command emits the standard JSON envelope (see core skill). When `error` is present, map `error.code` to a fix below.
Three rules:
1. **Map `error.code` to a fix below.** Most codes have a one-line resolution.
2. **`hint` is authoritative.** If it says "run: comfy launch", that's the fix. Don't paraphrase, don't guess.
3. **`details` carries the why.** Look here before scrolling logs.
## Decision tree for common failures
### `server_not_running` (local)
```
comfy launch # start the local server in the foreground
# or, for background mode:
comfy launch --background
```
If `comfy launch` itself fails: check `comfy --json env` for the resolved interpreter and workspace, and inspect whatever stdout `comfy launch` was attached to.
### `cloud_not_configured` / `cloud_unauthorized` (cloud)
```
comfy cloud login # opens browser, OAuth + PKCE
# or, if you already have an API key:
comfy cloud set-key --key sk-… # alternative path; API key is a fallback, not an override
comfy --json cloud whoami # confirm signed_in: true (auth_method is "oauth" or "api_key")
```
Auth precedence is **env first**: a credential handed in by the environment (`COMFY_CLOUD_AUTH_TOKEN`, then `COMFY_CLOUD_API_KEY`) outranks a live `comfy cloud login` session, which outranks a key saved with `comfy cloud set-key`. Empty or whitespace-only env values count as unset. While an env credential is set the stored session is not refreshed or used. `comfy --json cloud whoami` shows which credential is active in `credential_source`. If a stale session is causing 401s, `comfy cloud logout && comfy cloud login`, or unset the env credential if that is the one being refused.
If you're on a custom env (PR preview), set the base URL first:
```
comfy cloud set-base-url https://fe-pr-NNNNN.testenvs.comfy.org
```
**Do not confuse this with `transient_auth` (below).** `cloud_unauthorized` happens before submission (your CLI session); an "Unauthorized" that appears as a *job failure* is the server-side token expiry and re-login does nothing.
### `transient_auth` (cloud job failed with "Unauthorized: Please login first to use this node")
An API node's **server-side** session token expired mid-execution. It is transient and has nothing to do with your local credentials — `comfy cloud login` will NOT fix it, and your auth was fine at submit time (often it strikes minutes into a long render, sometimes a whole batch at once).
```
comfy --json run --workflow same_workflow.json --where cloud # just resubmit — succeeds on retry
```
If several jobs from one batch died together with this code, resubmit them all; one retry each is normally enough.
### `workflow_not_api_format`
UI-format workflows are converted to API format **client-side** using object_info (no server conversion endpoint exists). If conversion fails with `conversion_error`, re-export via `File > Export (API)` in ComfyUI; if object_info can't be fetched (`cql_no_graph`), retry (it's fetched live — check cloud sign-in/connection) or start a local server.
### `workflow_invalid_json`
The file isn't valid JSON. Inspect the first/last 100 bytes — often it's an HTML error page that was saved with `.json`.
### `prompt_rejected` (server returned `node_errors`)
The server validated the workflow and rejected nodes. The full per-node error map is in `details.node_errors`. The two most common causes:
- **Unknown class_type** → the cloud or local server lacks the custom node. Run:
```
comfy --json nodes search MissingNodeName
```
If `data.count` is 0 — or `data.close_match` is true, meaning the search found nothing and fell back to similarly-named classes — the node is genuinely absent. Then either install via `comfy node install <pkg>` (local) or pick a different workflow (cloud).
- **Missing model file** (`ckpt_name`, `lora_name`, `vae_name` not found) → confirm the loader node exists and see its choices:
```
comfy --json nodes show CheckpointLoaderSimple # inputs[].choices lists available checkpoints
comfy --json env # see workspace/models path
```
### `cloud_http_error` (HTTP 4xx/5xx from cloud)
`details.status` is the HTTP code. `details.body` is the truncated server response. Most common:
- `401 invalid auth token` → token audience mismatch. Decode the token at jwt.io or via `python3 -c 'import base64,json,sys; ...'` and check `aud`. The `aud` field must match what `/api/prompt` expects.
- `404` returning XML `<AuthenticationRequired>` → wrong path. Real ComfyUI endpoints on cloud live under `/api/*`; everything else hits the CDN catch-all.
- `503` → check the Comfy Cloud dashboard or server logs for deployment health.
### `cloud_rate_limited` (HTTP 429 from cloud)
Throttling is not a verdict on the workflow, so do not edit it. Wait `details.retry_after` seconds (when present; otherwise a few seconds). A 429 does not by itself prove a submit had no effect, so before re-running `comfy run`, check `comfy jobs ls --where cloud` for the job. A 429 while `--wait` polls means the job was already submitted: follow it with `comfy jobs watch <prompt_id> --where cloud` instead of re-running.
### `cloud_payment_required` (HTTP 402, or a legacy typed 429, from cloud)
The cloud refused the submit because the account's plan does not allow the run: free generations used up, a subscription required, or a partner node or model that needs a paid plan (`details.reason`, when the server sent a type). The cloud answers this with HTTP 402; older deployments sent a 429 whose body type is a plan refusal, so `details.status` is 402 or 429. Either way it is not throttling and not a problem with the workflow, and nothing was queued. Do not retry or edit the workflow: tell the user the server's message (`message`, `details.body`).
### `cloud_timeout`
`cloud_timeout` — the run went **silent** for `--timeout` seconds (default 120). `comfy run --timeout` is a per-event-silence deadline on both local and cloud: it resets whenever the job reports progress, so a workflow streaming progress can run indefinitely. Wall-clock limits exist only on `comfy jobs watch --max-wait` (default 600s, cloud). Recovery: re-run with a larger `--timeout`, or submit async and `comfy jobs watch <id>`.
```
RES=$(comfy --json run --workflow X.json --where cloud) # async by default
PID=$(echo "$RES" | jq -r .data.prompt_id)
comfy --json-stream jobs watch "$PID" --where cloud --max-wait 1800
```
### `ws_timeout` / `ws_disconnected` (local)
The WebSocket dropped mid-stream. Reconnect:
```
comfy jobs status <prompt_id> # one-shot snapshot
comfy --json-stream jobs watch <prompt_id> # re-attach
```
The local server keeps the job; the CLI just lost its tail.
### `cql_query_invalid`
`cql_query_invalid` — raised when a legacy `--query` string is passed to `comfy templates ls`. There is no query grammar; use flag-based filtering instead: `--type image|video|audio`, `--tag <t>`, `--model <m>` (templates) and `--produces/--accepts/--category/--pack` (`comfy nodes ls`).
### `cql_no_graph`
The CLI needs an `object_info.json` to query against. Two options:
```
comfy launch # then re-run the nodes command
comfy --json nodes ls --produces IMAGE --input /path/to/object_info.json
```
### `internal_error`
The command crashed on an exception it did not handle. This is a comfy-cli
bug, not a bad input. `details.exception` names the type and
`details.traceback` lists the innermost `file:line:func` frames. The full
traceback is on stderr. Re-read the file or state before retrying, because the
crash may have happened after a write. If the same call crashes again, take
another route (e.g. `set-slot` instead of `set-widget`, or a different address
form) and report the envelope as a bug. Do not retry it in a loop.
### `comfy generate` is partially machine-readable
`comfy generate` is partially machine-readable: `generate <model> --json` and
`generate resume <id> --json` print the raw API response as JSON;
`generate upload <file> --json` emits structured `{url, expires_at, ...}`;
`generate <model> --emit-workflow out.json` goes through the full renderer
envelope (`command: "generate emit-workflow"`, error code `emit_workflow_failed`).
The default proxy path (`generate <model>` without those flags) is still
pretty-only — don't parse it. Known sharp edge: `generate resume` for BFL can
raise a raw traceback on an expired/unknown id (HTTP 404 is unwrapped).
## Job-stuck triage
If a prompt seems to hang:
```
# 1. Is it still tracked?
comfy --json jobs ls
# 2. What does the server think?
comfy --json jobs status <prompt_id>
# 3. Watch live events (NDJSON, one per line)
comfy --json-stream jobs watch <prompt_id>
```
Three possible answers:
| Symptom | Likely cause | Fix |
|---|---|---|
| `status: pending`, `queue_position > 0` | Earlier jobs ahead of you | Wait or cancel them |
| `status: running` but no progress events | A long sampler step, or a hung custom node | Wait one sampler-step's worth; if still stuck, interrupt |
| `status: error` with no `error_message` | Server crashed mid-execution | Check the Comfy Cloud dashboard or server logs (cloud), or the stdout of `comfy launch` (local) |
## Interrupting / cancelling
```
comfy --json run --workflow X.json # async by default, returns a prompt_id
# later, if it's running too long:
comfy jobs cancel <prompt_id> # works on both local and cloud
```
## When `--json` makes diagnosis worse, not better
Pretty mode hides the envelope behind a rendered panel. If the rendered output is opaque, **always re-run with `--json`** — that's the contract. Conversely, if `--json` floods you with NDJSON, drop `-stream` to get a single envelope.
## What to NOT do
- Don't `chmod` files in the model dirs to "fix" load failures — the path is wrong, not the permissions.
- Don't delete the OAuth session to "reset" — that loses state. Use `comfy cloud logout` and `comfy skills uninstall` instead.
- Don't paste raw error messages into prompts without the `details` block — the details are usually what disambiguates the fix.
## Where to look when nothing in the envelope helps
1. `comfy --json env` → interpreter, workspace, server reachability, conda env
2. `comfy --json which` → resolved workspace path + how it was picked
3. `comfy --json cloud whoami` → cloud session state + base URL
4. Server logs:
- Local: whatever stdout `comfy launch` was attached to (foreground), or the journal/console for `comfy launch --background`
- Cloud: check the Comfy Cloud dashboard or server logs
5. The bundled `comfy` skill — re-read it; the right command for what you're trying to do is almost certainly already documented there.
Ver en GitHub