langchain-ai/deepagents · error · ExternalEditorError

External editor failed

Error message

External editor failed

What it means

The external editor process ran but failed for a reason other than a missing file — non-zero exit, crash, missing execute permission, or unusable terminal/display environment. The original exception is logged at warning level with a traceback (`logger.warning("Editor failed", exc_info=True)`), and with `raise_on_error=True` it is re-raised as `ExternalEditorError` with this generic message, chained to the cause.

Source

Thrown at libs/code/deepagents_code/editor.py:198

        # Strip exactly one so the cursor lands on content, not a blank line,
        # while preserving any intentional trailing newlines the user added.
        edited = edited.removesuffix("\n")

        # Chat composition historically treats a blank result as cancellation;
        # callers with their own submit-time validation may opt in to preserving it.
        if not allow_empty and not edited.strip():
            return None

    except FileNotFoundError as exc:
        if raise_on_error:
            msg = "External editor executable or temporary file was not found"
            raise ExternalEditorError(msg) from exc
        return None
    except Exception as exc:
        logger.warning("Editor failed", exc_info=True)
        if raise_on_error:
            msg = "External editor failed"
            raise ExternalEditorError(msg) from exc
        return None
    else:
        return edited
    finally:
        if tmp_path is not None:
            with contextlib.suppress(OSError):
                Path(tmp_path).unlink(missing_ok=True)

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Check the app logs for the 'Editor failed' warning — it contains the underlying exception and traceback.
  2. Run the editor command manually against a scratch file to reproduce its own error output.
  3. For remote sessions use a terminal editor or set up X/SSH display forwarding.
  4. Restore execute permission (`chmod +x`) on the editor binary if permission was denied.

Example fix

// before
EDITOR=gui-editor over SSH (no DISPLAY) -> ExternalEditorError
// after
export EDITOR=vim  # terminal-capable editor
Defensive patterns

Strategy: try-catch

Validate before calling

import os, shutil

def can_launch_editor(cmd: list[str]) -> bool:
    return bool(cmd) and shutil.which(cmd[0]) is not None and os.access(cmd[0], os.X_OK)

Try / catch

try:
    edited = open_in_editor(text, raise_on_error=True)
except ExternalEditorError as exc:
    logger.error("Editor failed: %r (cause: %r)", exc, exc.__cause__)
    edited = None

Prevention

When it happens

Trigger: `open_in_editor(raise_on_error=True)` where launching or awaiting the editor subprocess raises any exception besides `FileNotFoundError`: editor exits non-zero, is killed, lacks +x permission, or cannot open its display.

Common situations: GUI editor launched over SSH with no display ('Cannot open display'); editor script exiting 1 due to its own config errors; permission denied on the editor binary; editor killed by OOM or a timeout.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/076b8d94ff0355a0. Report an issue: GitHub.