Skip to content

Native Windows local mode: venv entrypoint uses .venv/bin/python + python3 causing exit_code=127 and stale-run recovery #170

@jamiechicago312

Description

@jamiechicago312

Summary

Running OpenHands Automations in local mode on native Windows (no WSL) can fail early with exit_code=127 (command not found). In practice this can trigger stale run recovery, causing duplicate automation runs and (for Slack Channel Monitor) two conversations for a single Slack message.

This is currently papered over in agent-canvas PR #1257 via Windows-only dev-time shims, but the correct fix belongs in this repo.

Symptoms

  • Automation run exits quickly with exit_code=127.
  • ~70 seconds later, the stale-run watchdog decides the run is stale and creates a recovery run.
  • Slack Channel Monitor posts two “On it!” links / opens two conversations.

Root causes

  1. Entrypoint uses python3

    • Many Windows installations provide python and/or the Python launcher py, but not python3.
  2. Unix venv path assumptions

    • Some code paths use Unix-style venv entrypoints like:
      • .venv/bin/python main.py
    • Native Windows venvs use:
      • .venv\\Scripts\\python.exe

From openhands/automation/preset_router.py today:

VENV_ENTRYPOINT = ".venv/bin/python main.py"

Expected

Local mode should work on native Windows (or fail with a clear, intentional error stating it's unsupported). If we want to support it, the automation entrypoint construction should be OS-aware.

Proposed fix

Make venv entrypoint construction cross-platform and resilient.

1) Add an OS-aware helper

Example approach:

import os
from pathlib import Path


def get_venv_python_entrypoint() -> str:
    # NOTE: we should not rely on `shutil.which` for a relative path.
    if os.name == "nt":
        # Native Windows virtualenv layout
        win = Path(".venv") / "Scripts" / "python.exe"
        if win.exists():
            return str(win)

    # Unix / WSL / macOS
    unix = Path(".venv") / "bin" / "python"
    if unix.exists():
        return str(unix)

    # Last resort: system python
    return "python"

2) Update preset router entrypoints

Instead of a hard-coded string constant for VENV_ENTRYPOINT, construct it dynamically using the helper:

  • prefer .venv/Scripts/python.exe on Windows
  • otherwise .venv/bin/python
  • otherwise fall back to python / py -3 depending on platform

3) Update execution command construction

In openhands/automation/execution.py, ensure the command construction uses the correct python executable and handles Windows path semantics when running under Git Bash/MSYS.

At minimum, avoid launching python3 unconditionally on Windows.

Reproduction notes

  • Windows 11
  • Git for Windows installed (Git Bash)
  • Node-based launcher agent-canvas starting the automation stack

Assignment

Assigning to @jamiechicago312 for follow-up.


This issue was created by an AI agent (OpenHands) on behalf of the user.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions