kestra-io / kestra-io/plugin-scripts

Python tasks fail with NullPointerException on Windows: HOME is not defined

Offen
#441 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
area/backend area/plugin
Vorherrschende Sprache
Java
Sterne
19
Forks
34
Ø Merge
2 T. 12 Std.
Gemergte PRs (30 T.)
9

Beschreibung

## What happens

On Windows, every `io.kestra.plugin.scripts.python.Script` task fails before `beforeCommands` or the script are reached:

```
java.lang.NullPointerException: Cannot invoke "java.lang.CharSequence.toString()" because "" is null
at java.base/java.lang.String.replace(Unknown Source)
at io.kestra.plugin.scripts.python.internals.PythonDependenciesResolver.getUvCmd(PythonDependenciesResolver.java:339)
at io.kestra.plugin.scripts.python.internals.PythonDependenciesResolver.findPython(PythonDependenciesResolver.java:566)
at io.kestra.plugin.scripts.python.internals.PythonDependenciesResolver.findLocalPythonVersion(PythonDependenciesResolver.java:152)
at io.kestra.plugin.scripts.python.internals.PythonEnvironmentManager.setup(PythonEnvironmentManager.java:79)
at io.kestra.plugin.scripts.python.Script.run(Script.java:358)
```

## Cause

`PythonDependenciesResolver.java:36`:

```java
private static final String HOME_ENV = System.getenv("HOME");
```

**Windows does not define `HOME`** (it has `USERPROFILE`), so `HOME_ENV` is `null`. Two consequences:

1. **Line 339** — `Optional.ofNullable(System.getenv("UV_PATH")).orElse("$HOME/.local/bin/uv".replace("$HOME", HOME_ENV))` → `String.replace(target, null)`. Because `orElse` evaluates its argument eagerly, this throws **even when `UV_PATH` is set**, so there is no way to configure around it.
2. **Lines 384, 540, 577** — `env.put("HOME", HOME_ENV)` on a `ProcessBuilder` environment. Windows' `ProcessEnvironment` rejects a null value, which surfaces as a second NPE: `Cannot invoke "String.indexOf(int)" because "" is null`.

Code is identical in `v1.9.8` and `v1.9.10`.

## Reproduction

Kestra 1.3.37 standalone on Windows Server 2022, `plugin-script-python` 1.9.8, Process task runner:

```yaml
id: python-probe
namespace: test
tasks:
- id: hello
type: io.kestra.plugin.scripts.python.Script
taskRunner:
type: io.kestra.plugin.core.runner.Process
script: |
print("hello")
```

Fails the same way with no Python installed, with system Python 3.12 + uv 0.12.15 on `PATH`, with a uv-managed interpreter and `UV_PYTHON_INSTALL_DIR` set, and with `pythonVersion` named explicitly.

## Confirmation

Setting `HOME` in the server's environment removes the NPE, and the resolver then works correctly on Windows:

```
uv --version → uv 0.12.15 (x86_64-pc-windows-msvc)
uv python find --system --no-managed-python → C:\Python312\python.exe
C:\Python312\python.exe --version → Python 3.12.10
```

(The task then needs `interpreter: ["cmd", "/c"]`, since `AbstractExecScript` defaults to `/bin/sh -c` — a separate matter — after which it runs: `cmd /c python3 …py`, exit 0.)

## Suggested fix

Resolve the home directory portably — `HOME`, then `USERPROFILE`, then `System.getProperty("user.home")`, which the JVM always sets — and make line 339 use `orElseGet` so the default path is not computed when `UV_PATH` is set. Happy to open a PR.

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Rechercherichtung

Beginnen Sie in PythonDependenciesResolver.java, insbesondere bei der HOME_ENV-Deklaration und den Zeilen 339, 384, 540 und 577, und verfolgen Sie dann den Aufruf von PythonEnvironmentManager.setup und Script.run. Reproduzieren Sie den Windows-Fehler mit der bereitgestellten Python-Aufgabe und verifizieren Sie, dass die Auflösung das Skript ohne HOME-bezogene Ausnahmen erreicht, auch wenn UV_PATH gesetzt ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
java, python
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Aktiv
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
76/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.