Skip to content

fix(presets): pin SDK install to the run venv so UV_PYTHON cannot redirect it - #392

Closed
santhiprakash wants to merge 1 commit into
OpenHands:mainfrom
santhiprakash:fix/preset-uv-python-redirect
Closed

fix(presets): pin SDK install to the run venv so UV_PYTHON cannot redirect it#392
santhiprakash wants to merge 1 commit into
OpenHands:mainfrom
santhiprakash:fix/preset-uv-python-redirect

Conversation

@santhiprakash

Copy link
Copy Markdown

Problem

Preset setup.sh creates a per-run venv and then installs the OpenHands SDK with a bare uv pip install. uv honours an ambient UV_PYTHON ahead of the .venv in the CWD, so when the agent-server's environment carries UV_PYTHON (e.g. it was launched via uvx/uv run), the install is silently redirected into a different environment: setup.sh prints [setup] Done and exits 0, the run venv stays empty, and the entrypoint fails with a confusing traceback that points at main.py:

ModuleNotFoundError: No module named 'openhands'

Reproduced locally with uv 0.11.7: with a 3.12 .venv in the CWD and UV_PYTHON pointing at a 3.13 environment, uv pip install six reports Using Python 3.13.13 environment at: fake-server-envsix lands in the 3.13 env, .venv/bin/python -c "import six" fails. Exactly the mechanism in #338 (which also documents the second-order damage: when the SDK version differs, the run overwrites the live agent-server's environment).

Closes #338.

Triage / Root cause

openhands/automation/presets/prompt/setup.sh:43 (and the byte-identical presets/plugin/setup.sh + scripts/test_tarball/setup.sh):

uv venv .venv --python '>=3.12' --quiet   # explicit flag: UV_PYTHON ignored here
uv pip install --quiet ...                # no flag: ambient UV_PYTHON wins over ./.venv

Fix

  • unset UV_PYTHON before the uv pip install in all three copies of the script, so no ambient value can redirect the install away from the run venv.
  • After the install, verify the SDK is importable from the run venv and fail loudly at the setup step (covering both POSIX .venv/bin/python and Windows .venv/Scripts/python.exe layouts — the entrypoint already supports both via _get_preset_entrypoint), so a misdirected install surfaces as [setup] ERROR: ... instead of a ModuleNotFoundError inside main.py.

I used unset UV_PYTHON rather than the --python .venv/bin/python variant sketched in the issue because hardcoding the POSIX venv path would break Windows sandboxes; with UV_PYTHON cleared, uv pip install resolves to the .venv in the CWD (which execution.py guarantees is the run's work dir) portably.

The secondary --python '>=3.12' free-threaded-interpreter issue from #338 is not addressed here (needs an interpreter-request policy decision) — happy to follow up separately.

Verification

  • Reproduced the redirect (old behavior) and the fix (new fragment installs into .venv; the import check fails loudly on an empty venv) — sequence quoted in the issue monitor notes.
  • bash -n clean on all three copies.
  • uv run pytest tests/ -q --ignore=tests/integration1463 passed, including 8 new regression tests asserting both preset copies (and the test-tarball copy) clear UV_PYTHON and verify the SDK import, and that the verification handles both venv layouts.
  • uv run pre-commit run --files <changed> → ruff format/lint, pycodestyle, pyright all pass.

Notes / Risks

HUMAN: Prepared by Santhi Prakash with AI assistance (code, verification, PR description); reviewed and submitted by Santhi Prakash.

…irect it

- Problem: an ambient UV_PYTHON (e.g. inherited from the agent-server's own
  uv/uvx launcher) takes precedence over the .venv in the CWD for
  'uv pip install', so preset setup.sh silently installs the SDK into a
  different environment: setup prints Done, the run venv stays empty, and
  main.py fails with ModuleNotFoundError (OpenHands#338).
- Fix: unset UV_PYTHON before the install in all three copies of the script
  (prompt/plugin presets + scripts/test_tarball), and verify the SDK imports
  from the run venv before handing off, covering both POSIX and Windows venv
  layouts so a misdirected install fails loudly at the setup step.
- Verification: reproduced the redirect with uv 0.11.7 (UV_PYTHON pointing at
  a 3.13 env while the CWD .venv is 3.12: install lands in the 3.13 env,
  .venv empty) and confirmed the fixed fragment installs into .venv and the
  import check fails loudly on an empty venv; uv run pytest tests/ -q
  --ignore=tests/integration -> 1463 passed (8 new regression tests);
  pre-commit (ruff/pycodestyle/pyright) clean; bash -n clean on all copies.
@github-actions github-actions Bot added the type: fix A bug fix label Aug 27, 2026
@santhiprakash

Copy link
Copy Markdown
Author

Closing for now to respect review bandwidth — we already have a few PRs queued in this repo. The branch stays up and the fix is complete; happy to reopen once the others land. Thanks!

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

Labels

type: fix A bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

setup.sh installs the SDK outside the run venv when UV_PYTHON is set — silent success, then ModuleNotFoundError in main.py

1 participant