BloopAI/vibe-kanban · error
failed to build releases HTTP client
Error message
failed to build releases HTTP client
What it means
This panic comes from the lazy initialization of the shared reqwest HTTP client used to fetch GitHub releases. `Client::builder().build()` returns a `Result` and only fails when the TLS backend cannot be initialized (or other builder settings are invalid, none of which are set here). Because the client is built via `OnceLock::get_or_init`, the panic fires on the first request to the /releases route, not at server startup.
Source
Thrown at crates/server/src/routes/releases.rs:26
use serde::{Deserialize, Serialize};
use tokio::sync::RwLock;
use crate::DeploymentImpl;
const CACHE_TTL: Duration = Duration::from_secs(15 * 60);
const GITHUB_API_URL: &str = "https://api.github.com/repos/BloopAI/vibe-kanban/releases";
type ReleasesCache = RwLock<Option<(Vec<GitHubRelease>, Instant)>>;
static HTTP_CLIENT: OnceLock<Client> = OnceLock::new();
static RELEASES_CACHE: OnceLock<ReleasesCache> = OnceLock::new();
fn client() -> &'static Client {
HTTP_CLIENT.get_or_init(|| {
Client::builder()
.user_agent("vibe-kanban-server")
.build()
.expect("failed to build releases HTTP client")
})
}
fn cache() -> &'static RwLock<Option<(Vec<GitHubRelease>, Instant)>> {
RELEASES_CACHE.get_or_init(|| RwLock::new(None))
}
pub fn router() -> Router<DeploymentImpl> {
Router::new().route("/releases", get(get_releases))
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct GitHubRelease {
pub name: String,
pub tag_name: String,
pub published_at: String,
pub body: String,
}View on GitHub (pinned to 4deb7eca8f)
Solutions
- Check the panic's underlying error (reqwest build error) to identify whether TLS/crypto backend initialization failed
- If using native-tls, install system CA certificates (e.g. `ca-certificates` package) or set SSL_CERT_FILE, or switch the client to the rustls-tls feature with `Client::builder().use_rustls_tls()`
- Rebuild the binary with the `rustls-tls` reqwest feature to avoid OpenSSL linking problems in cross-compiled or musl builds
- Replace the `.expect()` with graceful error handling so a failed client build returns a 503 from the route instead of panicking
- Verify the app runs in the same environment it was built/tested for (glibc vs musl, OpenSSL versions)
Example fix
// before
fn client() -> &'static Client {
HTTP_CLIENT.get_or_init(|| {
Client::builder()
.user_agent("vibe-kanban-server")
.build()
.expect("failed to build releases HTTP client")
})
}
// after
fn client() -> Option<&'static Client> {
HTTP_CLIENT.get_or_init(|| {
Client::builder()
.user_agent("vibe-kanban-server")
.build()
.ok()
})
} // route handler returns 503 when client() is None Defensive patterns
Strategy: fallback
Validate before calling
// Preflight TLS availability before relying on the releases client:
fn tls_available() -> bool {
reqwest::Client::builder()
.user_agent("vibe-kanban-server")
.build()
.is_ok()
} Try / catch
// In Rust, catch the panic or avoid it entirely by handling the Result:
let client = reqwest::Client::builder()
.user_agent("vibe-kanban-server")
.build();
match client {
Ok(c) => /* use c */,
Err(e) => tracing::error!("releases HTTP client unavailable: {}", e), // serve 503
} Prevention
- Use reqwest's rustls-tls feature to avoid native OpenSSL dependency issues
- Ensure CA certificates are installed in container/minimal images
- Wrap fallible OnceLock initialization in Result or Option instead of expect
- Test the binary in the deployment environment (distro, musl/glibc) before release
When it happens
Trigger: The first call to `client()` — i.e. the first GET to the `/releases` endpoint after cache miss — invokes `Client::builder().user_agent("vibe-kanban-server").build()`, which returns `Err` and trips the `.expect()`. The only realistic cause with just a user_agent configured is TLS backend (rustls/native-tls) initialization failure.
Common situations: Running the server binary in a stripped-down container or minimal Linux environment where the TLS backend's required root certificates or crypto library are missing; cross-compiled builds where native-tls/OpenSSL was not linked correctly; environments with no CA certificates installed so the TLS root store cannot be built.
Related errors
- failed to build reqwest client
- Failed to install rustls crypto provider
- Failed to install rustls crypto provider
- Failed to install rustls crypto provider
- Default profiles v3 JSON is invalid
AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29).
Data as JSON: /api/errors/acbed6d4d115b36f.
Report an issue: GitHub.