sqlalchemy/alembic · error · OSError

No suitable editor found. Please set the "EDITOR" or "VISUAL

Error message

No suitable editor found. Please set the "EDITOR" or "VISUAL" environment variables

What it means

Raised as OSError in _find_editor (editor.py:52) after exhausting every candidate: neither the EDITOR nor VISUAL env var resolves to an existing file/executable, and none of the default editors (sensible-editor, editor, nano, vim, code on posix; code.exe, notepad++.exe, notepad.exe on Windows) are found on PATH. This is a hard stop — Alembic cannot launch any editor.

Source

Thrown at alembic/util/editor.py:52

    except Exception as exc:
        raise CommandError("Error executing editor (%s)" % (exc,)) from exc


def _find_editor(environ: Mapping[str, str]) -> str:
    candidates = _default_editors()
    for i, var in enumerate(("EDITOR", "VISUAL")):
        if var in environ:
            user_choice = environ[var]
            if exists(user_choice):
                return user_choice
            if os.sep not in user_choice:
                candidates.insert(i, user_choice)

    for candidate in candidates:
        path = _find_executable(candidate, environ)
        if path is not None:
            return path
    raise OSError(
        "No suitable editor found. Please set the "
        '"EDITOR" or "VISUAL" environment variables'
    )


def _find_executable(candidate: str, environ: Mapping[str, str]) -> str | None:
    # Assuming this is on the PATH, we need to determine it's absolute
    # location. Otherwise, ``check_call`` will fail
    if not is_posix and splitext(candidate)[1] != ".exe":
        candidate += ".exe"
    for path in environ.get("PATH", "").split(os.pathsep):
        value = join(path, candidate)
        if exists(value):
            return value
    return None


def _default_editors() -> list[str]:

View on GitHub (pinned to 44fb345033)

Solutions

  1. Install any editor and ensure it is on PATH (e.g. `apt-get install nano`).
  2. Export EDITOR (or VISUAL) pointing to an installed editor: `export EDITOR=vim`.
  3. For scripted/non-interactive use, pass the message via -m to `alembic revision` to avoid editor invocation entirely.
  4. On Windows, confirm the editor .exe is in PATH or give EDITOR the full path.

Example fix

# before: no editor installed, no env var
alembic revision -m 'add col' --edit  # fails
# after: set EDITOR explicitly
export EDITOR=/usr/bin/vim
alembic revision -m 'add col'
# or skip the editor
alembic revision -m 'add col'
Defensive patterns

Strategy: validation

Validate before calling

import os, shutil
def ensure_editor_available() -> str:
    for var in ('EDITOR', 'VISUAL'):
        if os.environ.get(var) and (os.path.exists(os.environ[var]) or shutil.which(os.environ[var])):
            return os.environ[var]
    for cand in ('nano', 'vim', 'notepad.exe', 'code'):
        if shutil.which(cand):
            os.environ['EDITOR'] = cand
            return cand
    raise OSError('No editor found; install one or set EDITOR/VISUAL')

ensure_editor_available()

Try / catch

from alembic.util.editor import _find_editor
try:
    _find_editor(os.environ)
except OSError as e:
    os.environ['EDITOR'] = 'nano'  # or install one
    # retry

Prevention

When it happens

Trigger: Running `alembic edit` or `alembic revision` (which may open an editor for the message) on a minimal/containerized system with no editor installed and no EDITOR/VISUAL env var set.

Common situations: CI containers, Docker images, or fresh VMs that ship without vim/nano; SSH sessions where the local EDITOR env var isn't forwarded; Windows boxes with neither VS Code nor Notepad++ in PATH.

Related errors


AI-assisted analysis of sqlalchemy/alembic@44fb345033 (2026-08-04). Data as JSON: /data/errors/4a0b7c806fb1a0dd.json. Report an issue: GitHub.