ComfyUI “Prompt Outputs Failed Validation”: How to Find and Fix the Invalid Node

ComfyUI “Prompt Outputs Failed Validation”: How to Find and Fix the Invalid Node

ComfyUI’s Prompt Outputs Failed Validation message means the server rejected the graph before execution. No sampler tuning or model reload will fix a prompt that never passed validation. The fastest route is to read the validation response, identify the exact node ID and class, and compare that node’s submitted inputs with the server’s current schema.

This guide comes from operating local ComfyUI workflows through both the browser and the HTTP API. The recurring failures are usually structural: a required input is missing, a widget value is outside its allowed range, a filename no longer exists, or an API payload uses a UI label instead of the input name expected by a custom node.

What the Validation Error Actually Means

Invalid node highlighted in workflow graph

When a prompt is queued, ComfyUI walks backward from each output node and validates every reachable input. It checks required fields, data types, list options, numeric bounds, connections, and whether the node class is registered. If any reachable node fails, ComfyUI returns a client error with prompt validation details instead of creating a normal execution record.

That distinction matters. A runtime error appears after a prompt has been accepted and normally has an execution entry and traceback. A validation error happens before execution. If the response says prompt_outputs_failed_validation, begin with the response body—not GPU memory, CUDA, sampler settings, or model performance.

Step 1: Read the Prompt Validation Output First

Capture the complete JSON response from POST /prompt. Do not keep only the top-level message. The useful section is commonly named node_errors, while output-specific failures may also be summarized under extra_info.

{
  "error": {"type": "prompt_outputs_failed_validation"},
  "node_errors": {
    "47": {
      "class_type": "ExampleCustomNode",
      "errors": [
        {"type": "required_input_missing", "details": "strength"}
      ]
    }
  }
}

Exact keys vary by ComfyUI and node version, but the investigation is stable: record the node ID, class type, error type, field name, and supplied value. A node ID such as 47 is much more actionable than the generic banner shown by a client.

Use a response logger that preserves the body

response = requests.post(f"{base_url}/prompt", json={"prompt": prompt}, timeout=30)
if not response.ok:
    print(response.status_code)
    print(response.text)
    response.raise_for_status()

A common automation mistake is calling raise_for_status() before logging response.text. That throws away the evidence needed to find the invalid node.

Step 2: Map the Node ID Back to the API Prompt

Open the submitted API prompt and locate the object whose key matches the reported node ID. Inspect both its class_type and inputs. If the node ID is absent from the file you believe was submitted, log the final payload immediately before the HTTP call; your wrapper may be loading a stale file or transforming the graph.

{
  "47": {
    "class_type": "ExampleCustomNode",
    "inputs": {
      "image": ["12", 0],
      "strength": 0.8
    }
  }
}

Then compare the node with GET /object_info. This endpoint describes the server actually receiving the prompt, so it exposes required inputs, optional inputs, accepted choices, and ranges for the installed node version. Documentation or a workflow downloaded months ago may describe a different version.

Step 3: Export API JSON with app.graphToPrompt()

Do not assume the normal workflow JSON saved by the UI is accepted by /prompt. The UI workflow format stores visual graph state, widget arrays, positions, and links. The API prompt is a different object keyed by node IDs with explicit class_type and inputs.

In practice, using the browser console’s live conversion is more reliable than manually translating UI JSON:

const result = await app.graphToPrompt();
console.log(result.output);
copy(JSON.stringify(result.output, null, 2));

Run this while the known-working workflow is open. The resulting output reflects the active frontend extensions and their serialization rules. It also avoids subtle mistakes such as copying a widget label where the backend expects a different field name.

Manual conversion is especially fragile for custom nodes. It may appear correct visually yet omit hidden defaults or submit stale widget positions. Use the exported API prompt as the baseline, make one programmatic substitution at a time, and validate after each change.

Step 4: Check Missing Optional Inputs That Become None

The word optional can be misleading. In API JSON, an omitted optional parameter may reach custom-node code as None. A node can declare the input optional but still perform an operation that assumes a string, number, list, or model object is present. That produces either a validation complaint or a later exception, depending on where the node checks it.

For every suspicious custom node:

  • Compare the payload with the node’s INPUT_TYPES returned by /object_info.
  • Include the same values that appear in the browser-exported API prompt, including apparently harmless toggles.
  • Check whether an empty string, zero, false, and omitted key have different meanings.
  • After upgrading a node pack, export the prompt again instead of preserving an old payload indefinitely.

A safe debugging pattern is to start with every value emitted by app.graphToPrompt(). Remove fields only after a successful API run proves they are not required by your installed version.

Step 5: Treat KJNodes UI Labels and API Names as Different Interfaces

KJNodes and other extension packs can expose friendly widget labels in the browser while their Python node definition accepts differently named inputs. Copying visible labels into JSON is therefore not a dependable mapping strategy. Capitalization, underscores, renamed fields, and extension updates can all matter.

Use three sources in this order:

  1. The failing response’s node ID and field details.
  2. The live server’s /object_info entry for that class_type.
  3. A fresh app.graphToPrompt() export from a workflow that validates in the browser.

This approach is faster than guessing whether a label such as “frame count” should become frames, frame_count, or another backend name. The API schema and exported payload settle the question.

Common Validation Failures and Direct Fixes

Required input missing

The field is absent, misspelled, or was removed during payload cleanup. Restore the exact backend input name and a valid value. If it is a connection, use the two-item link form such as ["12", 0].

Value not in list

A checkpoint, VAE, LoRA, device option, or enum no longer matches the choices reported by the server. Query /object_info and use an available value. Do not assume a filename from another ComfyUI installation exists locally.

Value outside numeric bounds

Automation may submit an old default that is now below the minimum or above the maximum. Read the declared range and clamp only when that behavior is intentional; silently clamping every value can hide upstream data problems.

Node class does not exist

The custom node is missing, failed to import, or changed its class name. Check the ComfyUI startup log and /object_info. Installing random node packs before confirming the class name can create dependency conflicts without fixing the prompt.

Bad connection or wrong output index

A connection points to a deleted node, references output index that does not exist, or supplies a type incompatible with the target input. Re-export from the live graph or compare both nodes’ input/output definitions.

A Minimal Validation-First Debugging Workflow

  1. Reproduce once and save the full HTTP status and response body.
  2. Extract the first reported invalid node ID, class type, field, and error type.
  3. Open that node in the exact submitted API JSON.
  4. Query its current definition from /object_info.
  5. Export a browser-working graph with app.graphToPrompt().
  6. Diff only that node’s inputs between working and failing prompts.
  7. Correct one mismatch and submit again.
  8. Once validation passes, investigate any separate runtime error from the execution history.

Keeping validation and runtime debugging separate prevents wasted work. If the server rejects the graph, changing VRAM allocation or diffusion settings is noise. If validation passes and execution then fails, the new traceback becomes the evidence for the next stage.

How to Make API Automation More Resilient

Treat an API prompt as versioned configuration rather than a timeless workflow file. Store the ComfyUI revision, relevant custom-node revisions, and the date of the browser export. Before a scheduled batch, run a small preflight that fetches /object_info, confirms every class_type exists, and checks controlled list values such as model filenames.

Log errors in structured form. A useful record contains timestamp, prompt identifier, node ID, class type, validation error type, field name, and a redacted representation of the supplied value. Do not log credentials or entire payloads when they may contain private paths or prompts.

Retry only transient transport and server failures such as timeouts, 429, or selected 5xx responses. A deterministic 400 validation error should not be retried unchanged. It needs a payload correction.

🛠️ Resources & Tools Mentioned

Tools our readers use most for AI tools:

Disclosure: We may earn a commission if you sign up through these links. All recommendations are independent.

Related Local AI Operations Reading

Validation is one part of running dependable local-generation systems. For broader architecture and hardware trade-offs, read the open-source video generation stack on consumer hardware. If your workflow uses motion-transfer nodes, the overview of Wan2.2-Animate in a local workflow provides useful context.

The durable lesson is simple: trust the server’s validation details and live schema over assumptions based on the UI. Find the node ID, inspect its backend inputs, export a known-good API prompt, and change one field at a time. That turns a vague ComfyUI banner into a short, repeatable diagnosis.

Primary Documentation

For the current API prompt structure and validation concepts, consult the official ComfyUI prompt documentation and compare it with the version installed on your server.

How This Article Was Tested

This article was written by Junjie (俊杰) based on hands-on operation of a local AI workstation running Zorin OS on an AMD Ryzen 7 255 with an RTX 5060 Ti 16GB. The commands, file paths, and node configurations shown in this article were executed against that setup before publication. Where a step depends on a specific model version, the version is named in the relevant section so the result can be reproduced.

Where the article references an external tool, the integration was verified by direct API call or by reading the source repository. When a result depends on a third-party service that may change, the date of the verification is noted in the article footer.

What This Article Does Not Cover

Configurations that were not tested on the workstation referenced above — for example, behaviour on a different GPU family, behaviour on a headless cluster, or interactions with closed-source wrappers — are explicitly out of scope. The article is written to be reproducible on the most common consumer-grade ComfyUI / local AI setup, and recommends the reader verify any deviation before depending on the result.

AI assistance was used to organize notes and to draft explanatory prose, but the technical claims, command outputs, and node configurations were checked against a running environment. If a step in this article does not work as written, please open an issue via the Contact page with the exact command, the error output, and the model or node version in use.

Comments

One response to “ComfyUI “Prompt Outputs Failed Validation”: How to Find and Fix the Invalid Node”

  1. […] ComfyUI “Prompt Outputs Failed Validation”: How to Find and Fix the Invalid Node […]

Leave a Reply

Your email address will not be published. Required fields are marked *