Comfy-Org / Comfy-Org/ComfyUI

Loader Nodes don't check for None values in VALIDATE_INPUTS and fail when the input is a dynamically linked value - 'NoneType' object has no attribute 'endswith'

Open
#11,017 7 comments 0 reactions 0 assignees View on GitHub
Potential Bug
Dominant language
Python
Stars
133k
Forks
15.7k
Avg merge
1d 7h
Merged PRs (30d)
158

Description

### Custom Node Testing

- [x] I have tried disabling custom nodes and the issue persists (see [how to disable custom nodes](https://docs.comfy.org/troubleshooting/custom-node-issues#step-1%3A-test-with-all-custom-nodes-disabled) if you need help)

### Expected Behavior

Image

I want the `Load Image` node to load the image provided from the linked node.

### Actual Behavior

```NoneType object has no attribute 'endsWith'```

If I use a `Load Checkpoint` (`CheckpointLoaderSimple`) instead, it works.

Image

### Steps to Reproduce

connect the COMBO input with any string node which has output type any

### Debug Logs

```powershell
Failed to validate prompt for output 3:
* LoadImage 1:
- Exception when validating inner node: 'NoneType' object has no attribute 'endswith'
Output will be ignored
invalid prompt: {'type': 'prompt_outputs_failed_validation', 'message': 'Prompt outputs failed validation', 'details': '', 'extra_info': {}}
```

### Other

**exception is raised by**

`nodes.py`
```
class LoadImage:

def load_image(self, image):
image_path = folder_paths.get_annotated_filepath(image)
...
```

`folder_paths.py`
```
def annotated_filepath(name: str) -> tuple[str, str | None]:
if name.endswith("[output]"):
base_dir = get_output_directory()
name = name[:-9]
elif name.endswith("[input]"):
base_dir = get_input_directory()
name = name[:-8]
elif name.endswith("[temp]"):
base_dir = get_temp_directory()
name = name[:-7]
else:
return name, None

return name, base_dir
```

because `name=None`

**problem cause**
`execution.py`
```
async def validate_inputs(prompt_id, prompt, item, validated):
...
if len(validate_function_inputs) > 0 or validate_has_kwargs:
input_data_all, _, hidden_inputs = get_input_data(inputs, obj_class, unique_id)
...

def get_input_data(inputs, class_def, unique_id, execution_list=None, dynprompt=None, extra_data={}):
...
for x in inputs:
input_data = inputs[x]
_, input_category, input_info = get_input_info(class_def, x, valid_inputs)
def mark_missing():
missing_keys[x] = True
input_data_all[x] = (None,)
if is_link(input_data) and (not input_info or not input_info.get("rawLink", False)):
input_unique_id = input_data[0]
output_index = input_data[1]
if execution_list is None:
mark_missing()
continue # This might be a lazily-evaluated input
...
```

`input_data` is detected as a link, but `execution_list=None`, it's marked as missing, subsequently ignored(?) and results in `None`. Using Load Checkpoint instead: `execution_list=`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.