oraios/serena · critical · RuntimeError

Process terminated immediately with code {process.returncode

Error message

Process terminated immediately with code {process.returncode}. Error: {error_message}

What it means

RuntimeError raised in _start (src/solidlsp/ls_process.py:532) when the language-server subprocess exits (returncode is not None) immediately after launch. stderr is captured into the message, so the real startup failure reason (bad path, missing runtime, bad CLI flags) is included.

Source

Thrown at src/solidlsp/ls_process.py:532

    def is_running(self) -> bool:
        return self._process is not None and self._process.returncode is None

    def _start(self) -> None:
        log.info("Starting language server process via command: %s", self._process_launch_info.cmd)

        process = subprocess_util.ManagedSubprocessLauncher.get_instance().launch(
            self._process_launch_info, name=f"LS[{self.ls_id.value}]", start_new_session=self._start_independent_lsp_process
        )
        self._process = process

        # Check if process terminated immediately
        if process.returncode is not None:
            log.error("Language server has already terminated/could not be started")
            # Process has already terminated
            stderr_data = process.stderr.read() if process.stderr else b""
            error_message = stderr_data.decode("utf-8", errors="replace")
            raise RuntimeError(f"Process terminated immediately with code {process.returncode}. Error: {error_message}")

        # start threads to read stdout and stderr of the process
        threading.Thread(
            target=self._read_ls_process_stdout,
            name=f"LSP-stdout-reader:{self.ls_id.value}",
            daemon=True,
        ).start()
        threading.Thread(
            target=self._read_ls_process_stderr,
            name=f"LSP-stderr-reader:{self.ls_id.value}",
            daemon=True,
        ).start()

    def _stop(self, timeout: float) -> None:
        if self._process is None:
            log.debug("Server process is None, cannot shutdown.")
            return

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Read the stderr text in the error message — it names the actual startup failure.
  2. Verify the server executable path exists and is executable (e.g. `which <server>`).
  3. Install or reinstall the language server runtime (node, java, dotnet, etc.) at a compatible version.
  4. Check the language server's version against the one expected by the library.

Example fix

// before (server not on PATH)
SolidLSP(..., ls_specific_settings={"nodejs_path": "/nonexistent/node"})
// after
import shutil
assert shutil.which("node"), "node must be installed and on PATH"
SolidLSP(...)
Defensive patterns

Strategy: validation

Validate before calling

import shutil
server = cfg.binary_path
assert shutil.which(server) or os.path.isfile(server), f"server binary not found: {server}"
assert shutil.which("node") and node_version_at_least(18), "node >=18 required"

Type guard

def server_binary_ok(path: str) -> bool:
    return os.path.isfile(path) and os.access(path, os.X_OK)

Try / catch

try:
    ls = SolidLSP(cfg)
except RuntimeError as e:
    if "Process terminated immediately" in str(e):
        log.error("LS startup failed, stderr: %s", e)
        raise StartupError(str(e)) from e
    raise

Prevention

When it happens

Trigger: Starting a language server whose executable path doesn't exist, whose runtime (node/java/python) is missing or too old, or which exits at startup due to invalid arguments or version incompatibility.

Common situations: Language server not installed or not on PATH; wrong binary path in config; Java/Node version too old for the server; corrupted installation; sandbox/container lacking dependencies.

Related errors


AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29). Data as JSON: /api/errors/ba5cc0d02d100340. Report an issue: GitHub.