helix-editor/helix · error · helix_dap::Error

Command not provided

Error message

Command not provided

What it means

Returned by helix_dap::Client::process when the debug adapter's launch 'command' string is empty. The function is the single entry point that spawns a DAP adapter process (via stdio or TCP), and it refuses to spawn anything when no executable is configured. The debug config (command/args/transport) comes from the debugger entry in languages.toml or the config passed to the debug request.

Source

Thrown at helix-dap/src/client.rs:63

    /// Currently active frame for the current thread.
    pub active_frame: Option<usize>,
    pub quirks: DebuggerQuirks,
    /// The config which was used to start this debugger.
    pub config: Option<DebugAdapterConfig>,
}

impl Client {
    // Spawn a process and communicate with it by either TCP or stdio
    // The returned stream includes the Client ID so consumers can differentiate between multiple clients
    pub async fn process(
        transport: &str,
        command: &str,
        args: Vec<&str>,
        port_arg: Option<&str>,
        id: DebugAdapterId,
    ) -> Result<(Self, UnboundedReceiver<(DebugAdapterId, Payload)>)> {
        if command.is_empty() {
            return Result::Err(Error::Other(anyhow!("Command not provided")));
        }
        match (transport, port_arg) {
            ("tcp", Some(port_arg)) => Self::tcp_process(command, args, port_arg, id).await,
            ("stdio", _) => Self::stdio(command, args, id),
            _ => Result::Err(Error::Other(anyhow!("Incorrect transport {}", transport))),
        }
    }

    pub fn streams(
        rx: Box<dyn AsyncBufRead + Unpin + Send>,
        tx: Box<dyn AsyncWrite + Unpin + Send>,
        err: Option<Box<dyn AsyncBufRead + Unpin + Send>>,
        id: DebugAdapterId,
        process: Option<Child>,
    ) -> Result<(Self, UnboundedReceiver<(DebugAdapterId, Payload)>)> {
        let (server_rx, server_tx) = Transport::start(rx, tx, err, id);
        let (client_tx, client_rx) = unbounded_channel();

View on GitHub (pinned to 079a789e8c)

Solutions

  1. Set a non-empty command in your debug config: [[language.debuggers]] blocks in languages.toml or your debug config entry, e.g. command = "lldb-dap"
  2. Verify the template variables used in templated configs actually resolve (check for empty substitution) before launching
  3. Ensure the command is on PATH or use an absolute path
  4. If you intended to attach to an already-running TCP server, note Client::process still spawns the process that provides the port; use the attach/request type of your adapter accordingly

Example fix

# before (languages.toml / debug config)
[[language.debuggers]]
name = "rust"
transport = "stdio"
# command missing -> "Command not provided"

# after
[[language.debuggers]]
name = "rust"
command = "lldb-dap"
transport = "stdio"
Defensive patterns

Strategy: validation

Validate before calling

// Validate debug config before starting the session
fn validate_debug_config(cfg: &DebugConfig) -> Result<(), String> {
    if cfg.command.trim().is_empty() {
        return Err("debug config field 'command' is empty".into());
    }
    Ok(())
}

Try / catch

match dap::Client::process(transport, &command, args, port_arg, id).await {
    Ok((client, events)) => { /* ... */ }
    Err(e) => editor.set_error(format!("failed to start debugger: {e}")), // surfaces 'Command not provided'
}

Prevention

When it happens

Trigger: Starting a debug session (:debug or launch/debug templated config) where the resolved debug configuration has an empty or missing 'command' field — e.g. a [[language.debuggers]] block or user debug config without command = "...", or a template whose {command} variable resolves to an empty string.

Common situations: Copied a debugger config from docs but omitted the command line; used a templated debug config (e.g. lldb-dap vs codelldb) where the variable substitution produced an empty value; configured only transport/port for a server-style adapter but the client still requires the executable that launches it.

Related errors


AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16). Data as JSON: /api/errors/471af1201dbde9ed. Report an issue: GitHub.