{"record":{"id":"4a0b7c806fb1a0dd","repo":"sqlalchemy/alembic","slug":"no-suitable-editor-found-please-set-the-editor","errorCode":null,"errorMessage":"No suitable editor found. Please set the \"EDITOR\" or \"VISUAL\" environment variables","messagePattern":"No suitable editor found\\. Please set the \"EDITOR\" or \"VISUAL\" environment variables","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"error","filePath":"alembic/util/editor.py","lineNumber":52,"sourceCode":"    except Exception as exc:\n        raise CommandError(\"Error executing editor (%s)\" % (exc,)) from exc\n\n\ndef _find_editor(environ: Mapping[str, str]) -> str:\n    candidates = _default_editors()\n    for i, var in enumerate((\"EDITOR\", \"VISUAL\")):\n        if var in environ:\n            user_choice = environ[var]\n            if exists(user_choice):\n                return user_choice\n            if os.sep not in user_choice:\n                candidates.insert(i, user_choice)\n\n    for candidate in candidates:\n        path = _find_executable(candidate, environ)\n        if path is not None:\n            return path\n    raise OSError(\n        \"No suitable editor found. Please set the \"\n        '\"EDITOR\" or \"VISUAL\" environment variables'\n    )\n\n\ndef _find_executable(candidate: str, environ: Mapping[str, str]) -> str | None:\n    # Assuming this is on the PATH, we need to determine it's absolute\n    # location. Otherwise, ``check_call`` will fail\n    if not is_posix and splitext(candidate)[1] != \".exe\":\n        candidate += \".exe\"\n    for path in environ.get(\"PATH\", \"\").split(os.pathsep):\n        value = join(path, candidate)\n        if exists(value):\n            return value\n    return None\n\n\ndef _default_editors() -> list[str]:","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/sqlalchemy/alembic/blob/5551b5d35f985c99cb8f1af2b3c526b050e4c059/alembic/util/editor.py#L34-L70","documentation":"Raised as OSError by _find_editor when neither the EDITOR nor VISUAL environment variables are set AND none of the default editor candidates (sensible-editor, editor, nano, vim, code on POSIX; code.exe, notepad++.exe, notepad.exe on Windows) are found on PATH (editor.py:48-55). Alembic needs an editor for 'alembic edit' and interactive 'alembic revision' commands.","triggerScenarios":"Calling alembic edit <revision> or alembic revision (without -m) on a system where no editor is configured. The loop at editor.py:48-51 tries each default candidate via _find_executable and all return None.","commonSituations":"Minimal Docker/container environments with no editor installed. CI environments running interactive commands. Fresh server installs without dev tools. SSH sessions where EDITOR isn't propagated. Windows systems without VS Code or Notepad++.","solutions":["Set the EDITOR environment variable: export EDITOR=vim (or nano, code, etc.).","Install a common editor: apt-get install vim or apt-get install nano on Debian/Ubuntu.","Set VISUAL as an alternative: export VISUAL=code.","Use non-interactive mode to avoid the editor entirely: alembic revision -m 'description' instead of bare alembic revision.","For containers, add 'ENV EDITOR=vim' to the Dockerfile or install an editor in the image."],"exampleFix":"# before\nalembic edit abc123  # OSError: No suitable editor found\n\n# after\nexport EDITOR=vim\nalembic edit abc123\n\n# or skip the editor entirely\nalembic revision -m 'add users table'","handlingStrategy":"validation","validationCode":"import os\nfrom os.path import exists\n\ndef ensure_editor_available(environ=None):\n    env = environ or os.environ\n    if 'EDITOR' in env or 'VISUAL' in env:\n        return True\n    from alembic.util.editor import _default_editors, _find_executable\n    for candidate in _default_editors():\n        if _find_executable(candidate, env) is not None:\n            return True\n    return False","typeGuard":null,"tryCatchPattern":"from alembic.util.editor import _find_editor\n\ntry:\n    editor = _find_editor(os.environ)\nexcept OSError as e:\n    if 'No suitable editor' in str(e):\n        os.environ['EDITOR'] = 'vim'\n        editor = _find_editor(os.environ)\n    else:\n        raise","preventionTips":["Set EDITOR=vim (or nano) in your shell profile (~/.bashrc, ~/.zshrc).","In Dockerfiles, install an editor: RUN apt-get install -y vim.","Use non-interactive alembic commands (-m flag) in automation to avoid editor dependency."],"tags":["alembic","editor","environment","missing-dependency","oserror"],"backgroundTag":null,"analyzedSha":"5551b5d35f985c99cb8f1af2b3c526b050e4c059","analyzedAt":"2026-08-11T01:38:46.612Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}