microsoft/autogen · error · ValueError

Powershell or pwsh is not installed. Please install one of t

Error message

Powershell or pwsh is not installed. Please install one of them.

What it means

The code-block language normalizer in autogen_ext.code_executors._common maps 'pwsh', 'powershell', and 'ps1' to an actual PowerShell binary by probing PATH with shutil.which — first pwsh (PowerShell 7+), then the Windows-only powershell. If neither is found it raises ValueError telling you to install one. This is an environment requirement, not a code bug: executing PowerShell blocks requires a PowerShell runtime.

Source

Thrown at python/packages/autogen-ext/src/autogen_ext/code_executors/_common.py:169

PYTHON_VARIANTS = ["python", "Python", "py"]


def lang_to_cmd(lang: str) -> str:
    if lang in PYTHON_VARIANTS:
        return "python"
    if lang.startswith("python") or lang in ["bash", "sh"]:
        return lang
    if lang in ["shell"]:
        return "sh"
    if lang in ["pwsh", "powershell", "ps1"]:
        # Check if pwsh is available, otherwise fall back to powershell
        if shutil.which("pwsh") is not None:
            return "pwsh"
        elif shutil.which("powershell") is not None:
            return "powershell"
        else:
            raise ValueError("Powershell or pwsh is not installed. Please install one of them.")
    else:
        raise ValueError(f"Unsupported language: {lang}")


# Regular expression for finding a code block
# ```[ \t]*(\w+)?[ \t]*\r?\n(.*?)[ \t]*\r?\n``` Matches multi-line code blocks.
#   The [ \t]* matches the potential spaces before language name.
#   The (\w+)? matches the language, where the ? indicates it is optional.
#   The [ \t]* matches the potential spaces (not newlines) after language name.
#   The \r?\n makes sure there is a linebreak after ```.
#   The (.*?) matches the code itself (non-greedy).
#   The \r?\n makes sure there is a linebreak before ```.
#   The [ \t]* matches the potential spaces before closing ``` (the spec allows indentation).
CODE_BLOCK_PATTERN = r"```[ \t]*(\w+)?[ \t]*\r?\n(.*?)\r?\n[ \t]*```"


def infer_lang(code: str) -> str:
    """infer the language for the code.

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Install PowerShell 7: on Debian/Ubuntu follow Microsoft's install (or brew install --cask powershell on macOS); verify with pwsh --version
  2. In Docker: RUN apt-get update && apt-get install -y powershell (from the MS repo) or use the mcr.microsoft.com/powershell base image
  3. Prompt the model to emit bash/sh or python code blocks instead of PowerShell
  4. As a last resort, treat the error as a signal to rerun the block translated to python

Example fix

# before (Dockerfile)
FROM python:3.12-slim
RUN pip install autogen-ext
# powershell blocks fail: ValueError

# after
FROM python:3.12-slim
RUN wget -q https://github.com/PowerShell/PowerShell/releases/download/v7.4.6/powershell-7.4.6-linux-x64.tar.gz \
    && tar -xzf powershell-7.4.6-linux-x64.tar.gz -C /usr/local/pwsh \
    && ln -s /usr/local/pwsh/pwsh /usr/local/bin/pwsh
Defensive patterns

Strategy: fallback

Validate before calling

import shutil
def powershell_available() -> bool:
    return shutil.which('pwsh') is not None or shutil.which('powershell') is not None

Try / catch

try:
    result = await executor.execute_code(blocks, token)
except ValueError as e:
    if 'Powershell or pwsh' in str(e):
        blocks = [b for b in blocks if b.language not in ('pwsh', 'powershell', 'ps1')]
        result = await executor.execute_code(blocks, token)  # skip ps blocks
    else:
        raise

Prevention

When it happens

Trigger: An LLM emits a ```powershell code block that reaches LocalCommandLineCodeExecutor (or similar) on a Linux/macOS box or container where pwsh was never installed.

Common situations: Linux Docker images (python:*-slim, distroless) without PowerShell, macOS without brew install powershell, CI runners where only bash exists, agents prompted for Windows-style commands.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/9aa0f18a0697c02d. Report an issue: GitHub.