BoundaryML/baml · warning · LspError

-32803

-32803

Error message

LSP outbound sink is saturated

What it means

LspError::OutboundSaturated indicates bounded-transport backpressure: the outbound sink's buffer is full, so the server cannot immediately send a message. It maps to LSP RequestFailed error code -32803. Backpressure is a flow-control signal, not data corruption.

Solutions

  1. Retry the send after yielding (the sink may drain shortly); or await capacity asynchronously
  2. Coalesce/dedupe diagnostics so fewer messages are sent
  3. Increase the outbound channel capacity if the transport is legitimately undersized

Example fix

// before
sink.send(msg)?; // saturates under diagnostic bursts
// after (retry with yield)
for _ in 0..3 {
    match sink.try_send(msg.clone()) {
        Ok(()) => break,
        Err(LspError::OutboundSaturated) => tokio::time::yield_now().await,
        Err(e) => return Err(e),
    }
}
Defensive patterns

Strategy: retry

Type guard

fn is_saturated(e: &LspError) -> bool {
    matches!(e, LspError::OutboundSaturated)
}

Try / catch

loop {
    match sink.try_send(msg.clone()) {
        Ok(()) => break,
        Err(LspError::OutboundSaturated) => tokio::time::sleep(Duration::from_millis(10)).await,
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: Sending responses/notifications faster than the client drains the bounded channel; a burst of diagnostics or a large publishDiagnostics after a batch edit filling the sink capacity.

Common situations: Publishing diagnostics for every keystroke on a large project; slow or stalled client (frozen editor UI); misconfigured tiny sink buffer.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/dbb1b6be7a451811. Report an issue: GitHub.

Appendix: source

Thrown at baml_language/crates/baml_lsp/src/error.rs:25

/// Serialized to the wire exclusively through [`LspError::to_response_error`];
/// the legacy `-32001 UnknownErrorCode` is never emitted.
#[derive(Debug, thiserror::Error)]
pub enum LspError {
    #[error("{0}")]
    NotificationExtractError(lsp_server::ExtractError<lsp_server::Notification>),
    #[error("Notification not supported: {0}")]
    NotificationNotSupported(String),
    #[error("{0}")]
    RequestExtractError(lsp_server::ExtractError<lsp_server::Request>),
    #[error("Request not supported: {0}")]
    RequestNotSupported(String),
    #[error("Failed to serialize request result: {0}")]
    RequestSerializeError(serde_json::Error),
    /// The client's sink is gone; nothing more can be delivered.
    #[error("Client closed")]
    ClientClosed,
    /// Bounded transport backpressure (LSP `RequestFailed`, `-32803`).
    #[error("LSP outbound sink is saturated")]
    OutboundSaturated,
    /// A frame larger than the transport limit (LSP `RequestFailed`,
    /// `-32803`).
    #[error("LSP outbound frame exceeds the transport limit")]
    OutboundOversized,
    #[error("Invalid command arguments for command: {command}: {message}")]
    InvalidCommandArguments { command: String, message: String },
    #[error("File not found: {}", .0.display())]
    FileNotFound(PathBuf),
    #[error("Path is invalid: {}: {message}", path.display())]
    InvalidPath { path: PathBuf, message: String },
    /// The document's path is under no known source root.
    #[error("No source root contains {}", .0.display())]
    NoRootForPath(PathBuf),
    /// Cancellation claimed the response while the request was queued or
    /// running (LSP `RequestCanceled`, `-32800`).
    #[error("Request canceled: {0}")]
    RequestCanceled(String),

View on GitHub (pinned to bd85ce9dee)