helix-editor/helix · error · helix_dap::Error
Incorrect transport {}
Error message
Incorrect transport {} What it means
Returned by helix_dap::Client::process when the (transport, port_arg) pair is unusable: transport must be "stdio" (port_arg ignored) or "tcp" with a port_arg. The match falls through to this error for any unknown transport string and also for "tcp" without a port_arg, since the arm requires ("tcp", Some(_)).
Source
Thrown at helix-dap/src/client.rs:68
}
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();
let client = Self {
id,
_process: process,
server_tx,
request_counter: AtomicU64::new(0),View on GitHub (pinned to 079a789e8c)
Solutions
- Use transport = "stdio" for adapters Helix spawns and talks to over stdin/stdout (most common) - no port-arg needed
- For TCP adapters, keep transport = "tcp" AND provide port-arg (the argument template used to pass the chosen port, e.g. "--port="); if port-arg is missing you get this same error
- Check spelling and case: the match is exact ("tcp"/"stdio", lowercase)
- Confirm the value is not inherited empty from a template variable
Example fix
# before transport = "tcp" # no port-arg -> Incorrect transport tcp # after transport = "tcp" port-arg = "--port="
Defensive patterns
Strategy: validation
Validate before calling
fn transport_is_valid(transport: &str, port_arg: Option<&str>) -> bool {
match transport {
"stdio" => true,
"tcp" => port_arg.is_some(),
_ => false,
}
} Try / catch
// Client::process is async and returns Result; treat Error::Other with
// 'Incorrect transport' as a config bug, not a transient failure - do not retry:
if let Err(e) = dap::Client::process(...).await {
if e.to_string().contains("Incorrect transport") { fix_debug_config(); }
} Prevention
- Use exactly 'stdio' or 'tcp' (lowercase, no whitespace)
- Pair 'tcp' with a port-arg template like '--port='
- Lint debugger entries in languages.toml when adding them
When it happens
Trigger: Debug config with transport = "ws", "pipe", or any string other than "tcp"/"stdio"; or transport = "tcp" but no port-arg field supplied, which fails the ("tcp", Some(port_arg)) arm and lands in the catch-all. Also a typo like "Stdio" (case-sensitive match).
Common situations: Adapter docs mention connecting over TCP and the user sets transport = "tcp" but forgets port-arg (e.g. port-arg = "--port="); copied a config written for a different client whose transport names differ; capitalization/whitespace typos in the transport value.
Related errors
- Command not provided
- DAP request failed
- Failed to set breakpoints: {}
- Language server '{name}' not defined
- Failed to load config: {}
AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16).
Data as JSON: /api/errors/0097927087534c14.
Report an issue: GitHub.