helix-editor/helix · error · helix_dap::Error
DAP request failed
Error message
DAP request failed
What it means
Fallback message used when a Debug Adapter Protocol response arrives with success = false and the adapter supplied no human-readable 'message' field. It is wrapped as Error::Other(anyhow!(message)) after the 20s timeout and stream-closed checks already passed, so the request reached the adapter and was explicitly rejected.
Source
Thrown at helix-dap/src/client.rs:294
arguments,
};
server_tx
.send(Payload::Request(req))
.map_err(|e| Error::Other(e.into()))?;
// TODO: specifiable timeout, delay other calls until initialize success
let response = timeout(Duration::from_secs(20), callback_rx.recv())
.await
.map_err(|_| Error::Timeout(id))? // return Timeout
.ok_or(Error::StreamClosed)??;
if !response.success {
let message = response
.message
.clone()
.unwrap_or_else(|| "DAP request failed".to_string());
return Err(Error::Other(anyhow!(message)));
}
Ok(response.body.unwrap_or_default())
}
}
pub async fn request<R: helix_dap_types::Request>(
&self,
params: R::Arguments,
) -> Result<R::Result>
where
R::Arguments: serde::Serialize,
{
// a future that resolves into the response
let json = self.call::<R>(params).await?;
let response = serde_json::from_value(json)?;
Ok(response)
}View on GitHub (pinned to 079a789e8c)
Solutions
- Check the adapter's own log/stderr for the real rejection reason - this message means the adapter sent no explanation
- Rule out the startup race: retry the operation after the session is fully initialized/launched (e.g. set breakpoints after 'stopped' or launch completes)
- Verify the arguments (file paths must exist and be absolute; line numbers are converted internally) and the adapter's capabilities before issuing optional requests
- Update or switch the adapter (e.g. codelldb <-> lldb-dap) if the request is unsupported in your version
Defensive patterns
Strategy: try-catch
Validate before calling
// Before optional requests, gate on the adapter's capabilities:
if let Some(caps) = debugger.caps() {
if !caps.supports_configuration_done_request.unwrap_or(false) {
return Ok(()); // adapter will reject it
}
} Try / catch
// All dap::Client request wrappers return Result; handle Error::Other and
// keep the session alive - show the message but don't tear down:
match debugger.set_breakpoints(path, bps).await {
Ok(_) => {}
Err(dap::Error::Other(e)) => status_msg(format!("debugger rejected request: {e}")),
Err(dap::Error::Timeout(_)) => retry_once().await,
Err(dap::Error::StreamClosed) => restart_session(),
} Prevention
- Wait for initialize/launch/configurationDone before sending requests
- Check capabilities (caps) before optional requests (eval, conditional bps)
- Run the adapter with its own log enabled so rejections carry a real reason
- Treat this error as adapter-specific: reproduce outside Helix before filing bugs
When it happens
Trigger: Any dap::Client::request call whose response has success:false and message:None - commonly setBreakpoints before the adapter finished initializing, evaluate/continue while no thread is stopped, or a request the adapter lacks the capability for (checked against caps elsewhere).
Common situations: Race at session start: Helix sends a request before the initialize/launch handshake completes; adapter version change removed support for a request (e.g. unsupported breakpoint features); adapter-specific quirks (lldb-dap vs codelldb vs debugpy) rejecting arguments like invalid paths or 0-based/1-based line mismatches.
Related errors
- Command not provided
- Incorrect transport {}
- Failed to set breakpoints: {}
- Failed to parse snippet. Remaining input: {}
- Git command failed. Stdout: {} Stderr: {}
AI-assisted analysis of helix-editor/helix@079a789e8c (2026-08-16).
Data as JSON: /api/errors/d5036df9f05efa76.
Report an issue: GitHub.