{"record":{"id":"be06cb8ecf1f9c8c","repo":"gitui-org/gitui","slug":"editor-env-variable-found-empty","errorCode":null,"errorMessage":"editor env variable found empty: {}","messagePattern":"editor env variable found empty: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/popups/externaleditor.rs","lineNumber":89,"sourceCode":"\t\tlet editor = env::var(environment_options[0])\n\t\t\t.ok()\n\t\t\t.or_else(|| {\n\t\t\t\tget_config_string(repo, \"core.editor\").ok()?\n\t\t\t})\n\t\t\t.or_else(|| env::var(environment_options[1]).ok())\n\t\t\t.or_else(|| env::var(environment_options[2]).ok())\n\t\t\t.unwrap_or_else(|| String::from(\"vi\"));\n\n\t\t// TODO: proper handling arguments containing whitespaces\n\t\t// This does not do the right thing if the input is `editor --something \"with spaces\"`\n\n\t\t// deal with \"editor name with spaces\" p1 p2 p3\n\t\t// and with \"editor_no_spaces\" p1 p2 p3\n\t\t// does not address spaces in pn\n\t\tlet mut echars = editor.chars().peekable();\n\n\t\tlet first_char = *echars.peek().ok_or_else(|| {\n\t\t\tanyhow!(\n\t\t\t\t\"editor env variable found empty: {}\",\n\t\t\t\tenvironment_options.join(\" or \")\n\t\t\t)\n\t\t})?;\n\t\tlet command: String = if first_char == '\\\"' {\n\t\t\techars\n\t\t\t\t.by_ref()\n\t\t\t\t.skip(1)\n\t\t\t\t.take_while(|c| *c != '\\\"')\n\t\t\t\t.collect()\n\t\t} else {\n\t\t\techars.by_ref().take_while(|c| *c != ' ').collect()\n\t\t};\n\n\t\tlet remainder_str = echars.collect::<String>();\n\t\tlet remainder = remainder_str.split_whitespace();\n\n\t\tlet mut args: Vec<&OsStr> =","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/gitui-org/gitui/blob/2fa693cb6ed431b21ebc300dd02e83c2476699ce/src/popups/externaleditor.rs#L71-L107","documentation":"gitui picks the external editor from a chain of environment options (GIT_EDITOR-class, then EDITOR, then VISUAL) and falls back to vi only when none are SET. If a variable is set but to an empty string, env::var returns Ok(\"\"), the fallback never engages, and the peekable char iterator over the value is empty - .peek() yields None and this error names the offending variables (joined with ' or ').","triggerScenarios":"export EDITOR=\"\" or VISUAL=\"\" surviving into gitui's environment; container images that define EDITOR as empty to 'disable editors'; a shell rc exporting ${SOME_UNSET_VAR}, which expands to an empty string.","commonSituations":"Hardened no-editor container policies; miswritten dotfiles; variables inherited empty from a parent process or CI template.","solutions":["Unset the variable (unset EDITOR VISUAL) so gitui's vi fallback engages, or set it to a real editor (export EDITOR=nvim).","Audit shell rc files, Dockerfile ENV lines, and CI variable blocks for editor variables assigned empty strings.","If 'no editor' is intentional for your workflow, remap gitui's edit keys in key_config.ron instead of blanking EDITOR."],"exampleFix":"# Dockerfile\n# before\nENV EDITOR=\"\"\n# after: drop the line entirely, or\nENV EDITOR=vim\n\n// Rust callers: filter empties so fallbacks work\n// before\nlet editor = env::var(\"EDITOR\").ok().unwrap_or_else(|| \"vi\".into());\n// after\nlet editor = env::var(\"EDITOR\").ok().filter(|e| !e.is_empty())\n    .unwrap_or_else(|| \"vi\".into());","handlingStrategy":"validation","validationCode":"# shell: make the vi fallback reachable when 'set but empty'\n[ \"${EDITOR:-}\" ] || unset EDITOR\n[ \"${VISUAL:-}\" ] || unset VISUAL\n\n// Rust: filter empties when reading env vars with fallbacks\nenv::var(\"EDITOR\").ok().filter(|v| !v.is_empty())\n    .or_else(|| env::var(\"VISUAL\").ok().filter(|v| !v.is_empty()))\n    .unwrap_or_else(|| \"vi\".into())","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never export EDITOR/VISUAL as empty strings - unset them instead.","Avoid ENV EDITOR= in Dockerfiles unless a real binary follows the equals sign.","When reading env vars with fallbacks, always .filter(|v| !v.is_empty())."],"tags":["editor","env-var","empty-string","configuration"],"backgroundTag":"empty-env-var","analyzedSha":"2fa693cb6ed431b21ebc300dd02e83c2476699ce","analyzedAt":"2026-08-16T23:07:36.562Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}