Automated Image Optimization Fails Only with 1920 Version

Hello,

I'm working on a Server Connect workflow for automated, responsive image optimization (with cropping/resize and compression) and I'm encountering a persistent problem with the largest image version.

The goal is a top banner slider with six different sizes (from 1920x744 to 320x320).

Hello Community,

I'm working on a Server Connect workflow for automated, responsive image optimization (with cropping/resize and compression) and I'm facing a persistent problem with the largest image version.

The goal is a top banner slider with six different sizes (from 1920x744 to 320x320). My Setup and Procedure

  1. Central Database: I use a database table (responsive_image_settings) with specific values ​​for crop_start_px, resize_width, resize_height, and max_bytes (e.g., 250,000 bytes for version 1920).

  2. Workflow: The main workflow uses a repeat step on this database data.

  3. Optimization Loop: Within the repeat, the image is:

  • Cropped (crop_start_px 744 px) to correct the aspect ratio.

  • Resized to the target dimensions (e.g., 1920 x 744).

Then, a nested repeat loop (quality: 95 decreasing to 70) is used to save the image and check the file size.

  1. I don't yet have a stop logic; the loop simply runs continuously.

All smaller Image formats (1200 x 540, 970 x 450, etc.) work correctly and stop within the defined "max_bytes" limit.

The largest version (1920 x 744) ignores the "max_bytes" target value of 250,000 bytes and consistently returns the same uncompressed or only minimally compressed file (258,000 bytes) – even when I lower the target to 240,000 bytes.

It seems that the initial Image Save (at 90% quality) is not being overwritten by the "stat" check.

Question: Has anyone experienced this type of stat logic error in Wappler, which only occurs with the largest (often the first) image size? Do I need to handle the 1920px workflow differently (e.g., without the Crop step), or is the initial image instance locked?

{
  "meta": {
    "options": {
      "linkedFile": "/views/web-admin/images.ejs",
      "linkedForm": "formAdThumb"
    },
    "$_GET": [
      {
        "type": "text",
        "name": "sort"
      },
      {
        "type": "text",
        "name": "dir"
      }
    ],
    "$_POST": [
      {
        "type": "text",
        "fieldName": "imageAlt",
        "name": "imageAlt"
      },
      {
        "type": "text",
        "fieldName": "imageDescription",
        "name": "imageDescription"
      },
      {
        "type": "text",
        "name": "imageErstellt"
      },
      {
        "type": "text",
        "fieldName": "imageTitel",
        "name": "imageTitel"
      },
      {
        "type": "number",
        "fieldName": "imagekat",
        "options": {
          "rules": {
            "core:number": {}
          }
        },
        "name": "imagekat"
      },
      {
        "type": "text",
        "name": "image"
      }
    ]
  },
  "exec": {
    "steps": [
      {
        "name": "uploadImage",
        "module": "upload",
        "action": "upload",
        "options": {
          "path": "/public/assets/banner/basisfiles",
          "template": "{name}{ext}",
          "overwrite": true
        },
        "output": true,
        "meta": [
          {
            "name": "name",
            "type": "text"
          },
          {
            "name": "path",
            "type": "text"
          },
          {
            "name": "url",
            "type": "text"
          },
          {
            "name": "type",
            "type": "text"
          },
          {
            "name": "size",
            "type": "text"
          },
          {
            "name": "error",
            "type": "number"
          }
        ],
        "outputType": "array"
      },
      {
        "name": "queryGetImagedata",
        "module": "dbconnector",
        "action": "select",
        "options": {
          "connection": "db",
          "sql": {
            "type": "SELECT",
            "columns": [
              {
                "table": "responsive_image_settings",
                "column": "*"
              }
            ],
            "params": [],
            "table": {
              "name": "responsive_image_settings"
            },
            "primary": "id",
            "joins": [],
            "query": "select * from `responsive_image_settings`"
          }
        },
        "output": true,
        "meta": [
          {
            "type": "number",
            "name": "id"
          },
          {
            "type": "number",
            "name": "breite_px"
          },
          {
            "type": "number",
            "name": "hoehe_px"
          },
          {
            "type": "text",
            "name": "folder_name"
          },
          {
            "type": "number",
            "name": "crop_start_px"
          },
          {
            "type": "number",
            "name": "max_bytes"
          }
        ],
        "outputType": "array"
      },
      {
        "name": "repeatImagedata",
        "module": "core",
        "action": "repeat",
        "options": {
          "repeat": "{{queryGetImagedata}}",
          "outputFields": [],
          "exec": {
            "steps": [
              {
                "name": "imageName",
                "module": "core",
                "action": "setvalue",
                "options": {
                  "value": "{{uploadImage[0].name.replace('.jpg', '.webp').replace('.jpeg', '.webp').replace('.gif','.webp').replace('.png','.webp')}}"
                },
                "meta": [],
                "outputType": "text",
                "output": true
              },
              {
                "name": "image",
                "module": "image",
                "action": "load",
                "options": {
                  "path": "{{uploadImage[0].path}}"
                },
                "outputType": "object",
                "meta": [
                  {
                    "name": "width",
                    "type": "number"
                  },
                  {
                    "name": "height",
                    "type": "number"
                  }
                ]
              },
              {
                "name": "",
                "module": "image",
                "action": "crop",
                "options": {
                  "instance": "image",
                  "x": "center",
                  "y": "middle",
                  "width": "{{crop_start_px}}",
                  "height": 744
                }
              },
              {
                "name": "",
                "module": "image",
                "action": "resize",
                "options": {
                  "instance": "image",
                  "width": "{{breite_px}}",
                  "height": "{{hoehe_px}}"
                }
              },
              {
                "name": "quality",
                "module": "core",
                "action": "setvalue",
                "options": {
                  "value": "95,94,93,92,91,90,89,88,87,86,85,84,83,82,81,80,79,78,77,76,75,74,73,72,71,70"
                },
                "meta": [],
                "outputType": "text"
              },
              {
                "name": "repeat_quality",
                "module": "core",
                "action": "repeat",
                "options": {
                  "repeat": "{{quality.split(',')}}",
                  "outputFields": [],
                  "exec": {
                    "steps": [
                      {
                        "name": "stat",
                        "module": "fs",
                        "action": "stat",
                        "options": {
                          "path": "{{'/public/assets/banner/' + folder_name + '/' + imageName}}"
                        },
                        "output": true,
                        "outputType": "object",
                        "meta": [
                          {
                            "name": "type",
                            "type": "text"
                          },
                          {
                            "name": "name",
                            "type": "text"
                          },
                          {
                            "name": "path",
                            "type": "text"
                          },
                          {
                            "name": "url",
                            "type": "text"
                          },
                          {
                            "name": "size",
                            "type": "number"
                          },
                          {
                            "name": "folder",
                            "type": "text"
                          },
                          {
                            "name": "basename",
                            "type": "text"
                          },
                          {
                            "name": "extension",
                            "type": "text"
                          },
                          {
                            "name": "created",
                            "type": "date"
                          },
                          {
                            "name": "accessed",
                            "type": "date"
                          },
                          {
                            "name": "modified",
                            "type": "date"
                          }
                        ]
                      },
                      {
                        "module": "core",
                        "action": "condition",
                        "options": {
                          "if": "{{stat.size > max_bytes}}",
                          "then": {
                            "steps": {
                              "name": "newImage",
                              "module": "image",
                              "action": "save",
                              "options": {
                                "instance": "image",
                                "format": "webp",
                                "quality": "{{$value}}",
                                "overwrite": true,
                                "path": "{{'/public/assets/banner/' + folder_name}}",
                                "template": "{{imageName}}"
                              }
                            }
                          }
                        },
                        "outputType": "boolean"
                      }
                    ]
                  }
                },
                "meta": [
                  {
                    "name": "$index",
                    "type": "number"
                  },
                  {
                    "name": "$number",
                    "type": "number"
                  },
                  {
                    "name": "$name",
                    "type": "text"
                  },
                  {
                    "name": "$value",
                    "type": "object"
                  },
                  {
                    "name": "safe_in",
                    "type": "text",
                    "sub": []
                  },
                  {
                    "name": "stat",
                    "type": "object",
                    "sub": [
                      {
                        "name": "type",
                        "type": "text"
                      },
                      {
                        "name": "name",
                        "type": "text"
                      },
                      {
                        "name": "path",
                        "type": "text"
                      },
                      {
                        "name": "url",
                        "type": "text"
                      },
                      {
                        "name": "size",
                        "type": "number"
                      },
                      {
                        "name": "folder",
                        "type": "text"
                      },
                      {
                        "name": "basename",
                        "type": "text"
                      },
                      {
                        "name": "extension",
                        "type": "text"
                      },
                      {
                        "name": "created",
                        "type": "date"
                      },
                      {
                        "name": "accessed",
                        "type": "date"
                      },
                      {
                        "name": "modified",
                        "type": "date"
                      }
                    ]
                  }
                ],
                "outputType": "array",
                "output": true
              }
            ]
          }
        },
        "output": true,
        "meta": [
          {
            "name": "$index",
            "type": "number"
          },
          {
            "name": "$number",
            "type": "number"
          },
          {
            "name": "$name",
            "type": "text"
          },
          {
            "name": "$value",
            "type": "object"
          },
          {
            "name": "id",
            "type": "number"
          },
          {
            "name": "breite_px",
            "type": "number"
          },
          {
            "name": "hoehe_px",
            "type": "number"
          },
          {
            "name": "folder_name",
            "type": "text"
          },
          {
            "name": "crop_start_px",
            "type": "number"
          },
          {
            "name": "max_bytes",
            "type": "number"
          },
          {
            "name": "imageName",
            "type": "text",
            "sub": []
          },
          {
            "name": "repeat_quality",
            "type": "array",
            "sub": [
              {
                "name": "safe_in",
                "type": "text",
                "sub": []
              },
              {
                "name": "stat",
                "type": "object",
                "sub": [
                  {
                    "name": "type",
                    "type": "text"
                  },
                  {
                    "name": "name",
                    "type": "text"
                  },
                  {
                    "name": "path",
                    "type": "text"
                  },
                  {
                    "name": "url",
                    "type": "text"
                  },
                  {
                    "name": "size",
                    "type": "number"
                  },
                  {
                    "name": "folder",
                    "type": "text"
                  },
                  {
                    "name": "basename",
                    "type": "text"
                  },
                  {
                    "name": "extension",
                    "type": "text"
                  },
                  {
                    "name": "created",
                    "type": "date"
                  },
                  {
                    "name": "accessed",
                    "type": "date"
                  },
                  {
                    "name": "modified",
                    "type": "date"
                  }
                ]
              }
            ]
          }
        ],
        "outputType": "array"
      },
      {
        "name": "insertImage",
        "module": "dbupdater",
        "action": "insert",
        "options": {
          "connection": "db",
          "sql": {
            "type": "insert",
            "values": [
              {
                "table": "image",
                "column": "image",
                "type": "text",
                "value": "{{uploadImage[0].name.replace('.jpg', '.webp').replace('.gif', '.webp').replace('.jpeg', '.webp')}}"
              },
              {
                "table": "image",
                "column": "imagekat",
                "type": "number",
                "value": "{{$_POST.imagekat}}"
              },
              {
                "table": "image",
                "column": "imageTitel",
                "type": "text",
                "value": "{{$_POST.imageTitel}}"
              },
              {
                "table": "image",
                "column": "imageAlt",
                "type": "text",
                "value": "{{$_POST.imageAlt}}"
              },
              {
                "table": "image",
                "column": "imageDescription",
                "type": "text",
                "value": "{{$_POST.imageDescription}}"
              },
              {
                "table": "image",
                "column": "imageErstellt",
                "type": "text",
                "value": "{{NOW}}"
              }
            ],
            "table": "image",
            "returning": "imageID",
            "query": "insert into `image` (`image`, `imageAlt`, `imageDescription`, `imageErstellt`, `imageTitel`, `imagekat`) values (?, ?, ?, ?, ?, ?)",
            "params": [
              {
                "name": ":P1",
                "type": "expression",
                "value": "{{uploadImage[0].name.replace('.jpg', '.webp').replace('.gif', '.webp').replace('.jpeg', '.webp')}}",
                "test": ""
              },
              {
                "name": ":P2",
                "type": "expression",
                "value": "{{$_POST.imagekat}}",
                "test": ""
              },
              {
                "name": ":P3",
                "type": "expression",
                "value": "{{$_POST.imageTitel}}",
                "test": ""
              },
              {
                "name": ":P4",
                "type": "expression",
                "value": "{{$_POST.imageAlt}}",
                "test": ""
              },
              {
                "name": ":P5",
                "type": "expression",
                "value": "{{$_POST.imageDescription}}",
                "test": ""
              },
              {
                "name": ":P6",
                "type": "expression",
                "value": "{{NOW}}",
                "test": ""
              }
            ]
          }
        },
        "meta": [
          {
            "name": "identity",
            "type": "text"
          },
          {
            "name": "affected",
            "type": "number"
          }
        ]
      }
    ]
  },
  "usedModules": {
    "sharp": "^0.29.3"
  }
}

If i understand the logic correctly, i think the problem is caused by the order of steps in your workflow.
What happens is that your nested quality loop checks the file size before the new image is actually saved.
As a result, the first (largest) image is only written once and the next checks keep reading the same file size so it never re-saves or compresses further.

Try the following:
Inside your repeat_quality loop:

Move the Save Image step before the File/Folder Statistics check.
After saving, call File/Folder Statistics to read the new size.
If the size is now below or equal to max_bytes, use a break step to exit the loop.

Thanks Teodor, resizing to the target size works.
But the break stops all active repeats.

I need the repeatImagedata to process the different formats.

Can I solve this elegantly?

This is a bug, it should only break the repeat it is in and not the parent repeat.

I assume you are using NodeJS, here is an update.
core.zip (2.4 KB) unzip to lib/modules.

Thank you very much.
Unfortunately, it still doesn't work even after overwriting the core file.

Only the first two entries in the repeat are being processed.
The insert operation outside of the two repeats is also not being executed.

I updated the code manually, now it works.
Thank you so much! :grinning_face:

Code: "EBUSY" upload error

Hmm, now my script suddenly isn't working anymore.

{status: "500", code: "EBUSY",…}
code
: 
"EBUSY"
message
: 
"EBUSY: resource busy or locked, unlink 'C:\\Users\\chris\\Meine Ablage (christian.glinkemann@gmail.com)\\web\\relaunche\\public\\assets\\banner\\basisfiles\\show.jpg'"
stack
: 
"Error: EBUSY: resource busy or locked, unlink 'C:\\Users\\chris\\Meine Ablage (christian.glinkemann@gmail.com)\\web\\relaunche\\public\\assets\\banner\\basisfiles\\show.jpg'"
status
: 
"500"

I created a simple upload query for testing and I'm getting the same error.

1

I created a simple upload query for testing and I'm getting the same error.

2

3

Am I doing something wrong?

I think your project is under a bad location..
You have spaces and @ on the url
I recommend you avoid "@" and use underscore or camelCase instead of space

Sorry, that was my mistake.

If you try to upload an image to the same folder as the original, it won't work. :man_facepalming:

Here you have two request with error, both are the same? Or there's another message?