{"record":{"id":"8bb1d5300bce5535","repo":"jesseduffield/lazydocker","slug":"no-editor-defined-in-visual-or-editor","errorCode":null,"errorMessage":"No editor defined in $VISUAL or $EDITOR","messagePattern":"No editor defined in \\$VISUAL or \\$EDITOR","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/os.go","lineNumber":193,"sourceCode":"\tcommand := utils.ResolvePlaceholderString(commandTemplate, templateValues)\n\terr := c.RunCommand(command)\n\treturn err\n}\n\n// EditFile opens a file in a subprocess using whatever editor is available,\n// falling back to core.editor, VISUAL, EDITOR, then vi\nfunc (c *OSCommand) EditFile(filename string) (*exec.Cmd, error) {\n\teditor := c.getenv(\"VISUAL\")\n\tif editor == \"\" {\n\t\teditor = c.getenv(\"EDITOR\")\n\t}\n\tif editor == \"\" {\n\t\tif err := c.RunCommand(\"which vi\"); err == nil {\n\t\t\teditor = \"vi\"\n\t\t}\n\t}\n\tif editor == \"\" {\n\t\treturn nil, errors.New(\"No editor defined in $VISUAL or $EDITOR\")\n\t}\n\n\treturn c.NewCmd(editor, filename), nil\n}\n\n// Quote wraps a message in platform-specific quotation marks\nfunc (c *OSCommand) Quote(message string) string {\n\tvar quote string\n\tif c.Platform.os == \"windows\" {\n\t\tquote = `\\\"`\n\t\tmessage = strings.NewReplacer(\n\t\t\t`\"`, `\"'\"'\"`,\n\t\t\t`\\\"`, `\\\\\"`,\n\t\t).Replace(message)\n\t} else {\n\t\tquote = `\"`\n\t\tmessage = strings.NewReplacer(\n\t\t\t`\\`, `\\\\`,","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/jesseduffield/lazydocker/blob/7e7aadc2071d58031bf2daafca1fbd4093efc23f/pkg/commands/os.go#L175-L211","documentation":"Thrown by OSCommand.EditFile when no editor can be resolved: $VISUAL is empty, $EDITOR is empty, and `which vi` finds nothing. lazydocker uses the editor to open compose/config files (the 'e' key), and this chain is its entire fallback strategy — there is no built-in default beyond trying vi.","triggerScenarios":"Pressing 'e' to edit a file (docker-compose.yml, service config) on a machine where VISUAL and EDITOR are unset and vi is not installed — most commonly minimal Docker containers, slim dev images, or fresh systems without vim.","commonSituations":"Running lazydocker inside a container (alpine/distroless without vi); environments launched from a GUI/launcher that drops shell env vars; Windows systems where EDITOR is rarely set; stripped-down servers with only nano installed.","solutions":["Export an editor in your shell profile: `export EDITOR=nano` (or vim/code) in ~/.bashrc or ~/.zshrc, then restart the terminal.","Install vi/vim: `apt install vim` / `apk add vim` / `yum install vim-minimal`.","Set VISUAL instead of/alongside EDITOR — it is checked first.","For GUI launchers, ensure the environment variable is set globally (e.g. /etc/environment) since launcher-spawned processes don't read shell rc files."],"exampleFix":"# before\n# (nothing set; vi absent)\n$ lazydocker   # pressing 'e' fails\n\n# after\n$ echo 'export EDITOR=vim' >> ~/.bashrc && source ~/.bashrc\n$ lazydocker","handlingStrategy":"validation","validationCode":"editor := os.Getenv(\"VISUAL\")\nif editor == \"\" {\n    editor = os.Getenv(\"EDITOR\")\n}\nif editor == \"\" {\n    if _, err := exec.LookPath(\"vi\"); err != nil {\n        return fmt.Errorf(\"set $EDITOR (e.g. export EDITOR=vim) before using edit features\")\n    }\n    editor = \"vi\"\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set EDITOR (and VISUAL) in your shell profile on every machine you use lazydocker on.","Install at least one CLI editor (vim/nano) so the vi fallback resolves.","For containerized use, bake the editor and env var into the image."],"tags":["environment-variables","editor","configuration","setup"],"backgroundTag":null,"analyzedSha":"7e7aadc2071d58031bf2daafca1fbd4093efc23f","analyzedAt":"2026-08-15T09:51:48.093Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}