[gimp] Script-Fu targets the GIMP 2.10 PDB - GIMP 3 hangs for the full subprocess timeout on every render

Author: SleepyOldOrbsCreated Jul 22, 2026Updated Aug 21, 2026

[gimp] Script-Fu targets the GIMP 2.10 PDB — GIMP 3 hangs for the full subprocess timeout on every render

Severity: high — with GIMP 3 installed the harness is worse than with no GIMP at all Fix: a Script-Fu port, plus two smaller invocation fixes

Summary

Three separate problems compound. Together they mean that installing the documented dependency (requires: gimp) turns a fast, clean Pillow fallback into a 120-second stall per render.

Without GIMP on $PATH: find_gimp() raises, render() falls back to Pillow, works fine. With GIMP 3 on $PATH: every render blocks until subprocess.run(timeout=120) fires, then falls back to Pillow and produces the identical result.

More installed software → strictly worse behaviour.

Problem 1 — the GUI binary is selected for batch work

gimp/agent-harness/cli_anything/gimp/utils/gimp_backend.py:27

for name in ("gimp", "gimp-2.10", "gimp-2.99"):

gimp-console* is never searched, and no GIMP 3 name appears. On Windows, shutil.which("gimp") resolves to gimp.EXE — the GUI executable — which never exits in batch mode even with -i.

The correct binary sits beside it and responds instantly:

$ gimp-console-3.2.exe --version
GNU Image Manipulation Program version 3.2.4

Problem 2 — GIMP 3 requires an explicit batch interpreter

gimp_backend.py:61

cmd = [gimp, "-i", "-b", script, "-b", "(gimp-quit 0)"]

GIMP 3 no longer defaults -b to Script-Fu. Measured with gimp-console-3.2:

-i -b '(gimp-quit 0)'                                             HUNG (>40s)
-i --batch-interpreter plug-in-script-fu-eval -b '(gimp-quit 0)'  EXITED

Problem 3 — the emitted Script-Fu uses procedures GIMP 3 removed

Even with 1 and 2 fixed, renders still hang. The payload the harness emits:

(let* ((image (car (gimp-image-new 200 150 RGB)))
       (layer (car (gimp-layer-new image 200 150 RGB-IMAGE "BG" 100 LAYER-MODE-NORMAL))))
  (gimp-image-insert-layer image layer 0 -1)
  (gimp-image-set-active-layer image layer)
  (gimp-palette-set-foreground '(0 0 255))
  (gimp-edit-fill layer FILL-FOREGROUND)
  (file-jpeg-save RUN-NONINTERACTIVE image layer "..." "..." 0.85 0.0 0 0 "" 0 1 0 2)
  (gimp-image-delete image))

Probed individually against GIMP 3.2.4:

[valid  (gimp-version)]              EXIT: batch command executed successfully
[bogus  (no-such-proc)]              HUNG
[gimp3  gimp-context-set-foreground] EXIT: batch command executed successfully
[gimp2  gimp-palette-set-foreground] HUNG

Two findings:

  1. gimp-palette-set-foreground no longer exists in GIMP 3 (replaced by gimp-context-set-foreground). gimp-image-get-active-drawable, gimp-image-set-active-layer and the file-*-save signatures changed too.
  2. GIMP 3 batch mode hangs on any script error rather than exiting non-zero. So every removed procedure costs a full timeout instead of a fast failure.

Note the module header still says apt install gimp, and registry.json says requires: gimp (apt install gimp) — on current distros that now installs GIMP 3. This is version drift, not a Windows issue: GIMP 3 on Ubuntu would hit it too.

Reproduce

export PATH="/path/to/gimp-3/bin:$PATH"
python -m pytest gimp/agent-harness/cli_anything/gimp/tests -q

Without a per-test timeout the suite hangs indefinitely and leaves orphaned gimp processes behind.

Suggested fixes

Short term — stop the hang, keep the documented Pillow fallback fast. Detect the major version and report GIMP 3 as unavailable until the Script-Fu is ported:

def is_available() -> bool:
    try:
        gimp = find_gimp()
    except RuntimeError:
        return False
    try:
        version = subprocess.run([gimp, "--version"],
                                 capture_output=True, text=True, timeout=30).stdout
    except (subprocess.SubprocessError, OSError):
        return False
    match = re.search(r"version (\d+)\.", version)
    return bool(match) and int(match.group(1)) < 3

Plus prefer the console binary and pass the interpreter explicitly:

for name in ("gimp-console-3.2", "gimp-console-3", "gimp-console",
             "gimp-console-2.10", "gimp-console-2.99",
             "gimp", "gimp-2.10", "gimp-2.99"):
cmd = [gimp, "-i", "--batch-interpreter", "plug-in-script-fu-eval",
       "-b", script, "-b", "(gimp-quit 0)"]

Long term — port the Script-Fu to the GIMP 3 PDB, or pick a supported major version and enforce it loudly at startup.

Verified

With all three changes:

Before After
Test suite (GIMP 3 on PATH) hung indefinitely 113 passed / 2 failed, terminates in 122 s
export render via CLI ~120 s stall 0.2 s

The 2 remaining failures are TestGIMPRenderE2E::test_create_and_export_{png,jpeg}, which call render_project() directly and bypass is_available(). They exercise the 2.10 Script-Fu and will keep failing until it is ported — which is the real fix.

Environment

OS Windows 11 Pro 10.0.26100
Python 3.14.6
GIMP 3.2.4
Repo bc536c9 (2026-07-09)