Skip to content

Image loaded into a node is zeroed on disk, including a file already in {inputs} #5586

Description

@griptapeops

Problem

Loading an image from outside the workspace into a LoadImage node produces a 0-byte file in {inputs}, and the image renders broken. Re-evaluating the node truncates a previously-good file back to 0 bytes.

Expected: the external file is copied into {inputs} intact, and an existing file with the same name is never clobbered — the copy_external_file situation declares CREATE_NEW, so a second load should allocate name_001.png.

Origin

Reported by Jason Schleifer on main. Reproducible: pick any image from a directory outside the workspace in LoadImage. The source file is valid (confirmed intact PNG); the emptiness is introduced on our side.

Impact

Loading external images — the common first step in most workflows — silently produces empty files. Worse, a file the user copied into {inputs} by hand gets destroyed the next time the node evaluates, so the manual workaround doesn't hold.

Repro / evidence

  1. Put an image outside the workspace.
  2. In LoadImage, browse to it and select it.
  3. The preview is broken and {inputs}/images/<name>.png is 0 bytes.
  4. Copy the image into {inputs} manually, select it, then evaluate the node — it is truncated to 0 bytes again.

Warning logged during the copy:

WARNING  Attempted to identify the format of bytes destined for '/Users/<user>/.../GriptapeNodes/inputs/images/<name>.png'.
         Could not recognize the bytes as a known file format, so the file will be written with its requested '.png'
         extension unchanged.

Two things line up with the symptoms:

  • LocalStorageDriver.create_signed_upload_url writes an empty placeholder (content=b"", local_storage_driver.py) to claim the destination before handing out the PUT url. That empty write is what the format sniffer is complaining about — the bytes it is asked to identify are the placeholder's, not the image's. So the warning fires on the normal path and is misleading.
  • on_handle_create_static_file_upload_url_request (static_files_manager.py) calls create_signed_upload_url(resolved.path, file_metadata=resolved.file_metadata) and does not pass resolved.policy, so the call takes the parameter default ExistingFilePolicy.OVERWRITE instead of the CREATE_NEW the situation declares. save_static_file threads the resolved policy through; this path does not.

That accounts for the broken first render (the display url is served while only the placeholder exists), the re-zeroing on evaluate (a second upload-url request overwrites the good file with the placeholder rather than allocating an indexed name), and why a manual copy alone works (no upload-url request, so no placeholder).

No unit test covers the manager's upload-url path passing the resolved policy through — tests/unit/drivers/storage/test_base_storage_driver.py covers the driver-level pass-through only.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingengineTopics related to how the engine runs and evaluates

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions