BoundaryML/baml · error · anyhow::Error

Playground server error: {e}

Error message

Playground server error: {e}

What it means

The run function starts the axum HTTP/WebSocket server for the playground; if axum::serve itself returns an error while accepting/serving connections, it is wrapped in this anyhow error. This is a runtime server failure after successful binding, not a configuration problem.

Source

Thrown at baml_language/crates/baml_lsp_server/src/playground_server.rs:812

        seam,
        broadcast_tx,
        env_state,
        io_state,
        run_store,
        playground_dir_override,
        lsp_out_tx,
        lsp_runtime,
        doc_mirror,
        workspace_roots.into(),
        access_guard,
        current_open_target,
    )?;

    tracing::info!("Playground: http://localhost:{}", local_addr.port());

    axum::serve(listener, app)
        .await
        .map_err(|e| anyhow::anyhow!("Playground server error: {e}"))
}

#[allow(clippy::too_many_arguments)]
fn build_router(
    seam: Arc<PlaygroundSeam>,
    broadcast_tx: broadcast::Sender<WsOutMessage>,
    env_state: Arc<PlaygroundEnvState>,
    io_state: Arc<PlaygroundIoState>,
    run_store: Arc<InMemoryRunStore>,
    playground_dir_override: Option<PathBuf>,
    lsp_out_tx: broadcast::Sender<crate::OutboundFrame>,
    lsp_runtime: Arc<crate::lsp_runtime::LspRuntime>,
    doc_mirror: DocMirror,
    workspace_roots: Arc<[PathBuf]>,
    access_guard: PlaygroundAccessGuard,
    current_open_target: crate::playground_sender::SharedOpenTarget,
) -> anyhow::Result<Router> {
    let value_store = Arc::new(Mutex::new(LiveValueCache::with_max_bytes(

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Check server logs for the underlying axum/io error to identify the socket failure.
  2. Raise the file-descriptor limit (ulimit -n) if EMFILE occurred.
  3. Restart the playground/LSP server to recreate the listener.
  4. Update axum/tokio if the failure traces to a known framework bug.
Defensive patterns

Strategy: try-catch

Try / catch

match run(...).await {
    Err(e) if e.to_string().starts_with("Playground server error") => {
        tracing::error!("playground crashed: {e:#}; restarting");
        restart_server();
    }
    Err(e) => return Err(e),
    Ok(()) => {}
}

Prevention

When it happens

Trigger: axum::serve(listener, app).await returning Err — typically the accept loop failing, e.g. the listener socket being closed under the server, EMFILE (too many open files), or an OS-level socket error mid-serve.

Common situations: File-descriptor exhaustion under many WebSocket connections; system suspend/resume breaking the socket; the process hitting ulimit -n; abnormal termination of the network stack in containers.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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