BloopAI/vibe-kanban · error
client preview proxy port already set
Error message
client preview proxy port already set
What it means
set_preview_proxy_port stores the proxy port in a once-only field of client_info; the .expect("client preview proxy port already set") panics if the port was already set earlier in the process. Like the sibling set_server_addr call, this is a set-once invariant asserted during startup.
Source
Thrown at crates/server/src/main.rs:140
if let Err(e) = write_port_file_with_proxy(actual_main_port, Some(actual_proxy_port)).await {
tracing::warn!("Failed to write port file: {}", e);
}
tracing::info!(
"Main server on :{}, Preview proxy on :{}",
actual_main_port,
actual_proxy_port
);
deployment
.client_info()
.set_server_addr(main_listener.local_addr()?)
.expect("client server address already set");
deployment
.client_info()
.set_preview_proxy_port(actual_proxy_port)
.expect("client preview proxy port already set");
let app_router = routes::router(deployment.clone());
// Production only: open browser
if !cfg!(debug_assertions) {
tracing::info!("Opening browser...");
let browser_port = actual_main_port;
tokio::spawn(async move {
if let Err(e) =
utils::browser::open_browser(&format!("http://127.0.0.1:{browser_port}")).await
{
tracing::warn!(
"Failed to open browser automatically: {}. Please open http://127.0.0.1:{} manually.",
e,
browser_port
);
}
});View on GitHub (pinned to 4deb7eca8f)
Solutions
- Audit the startup path so set_preview_proxy_port is invoked exactly once.
- If reconfiguration is expected, switch the field to a replaceable container (RwLock<Option<u16>>) instead of once-only semantics.
- Downgrade the expect to a logged no-op if overwriting is harmless in your deployment.
Example fix
// before
deployment.client_info().set_preview_proxy_port(actual_proxy_port)
.expect("client preview proxy port already set");
// after
deployment.client_info().set_preview_proxy_port(actual_proxy_port)
.unwrap_or_else(|_| tracing::warn!("preview proxy port already set; ignoring")); Defensive patterns
Strategy: validation
Validate before calling
if deployment.client_info().preview_proxy_port().is_none() {
deployment.client_info().set_preview_proxy_port(actual_proxy_port)?;
} Try / catch
deployment.client_info()
.set_preview_proxy_port(actual_proxy_port)
.unwrap_or_else(|_| tracing::debug!("preview proxy port already configured")); Prevention
- Keep proxy initialization in one place; do not duplicate it across dev/prod branches.
- Never wrap once-only setters in retry loops or functions invoked twice.
- Prefer idempotent setters (last-write-wins) for configuration values.
- Add a startup smoke test covering the full init sequence to catch double-set panics.
When it happens
Trigger: The preview proxy port was already configured before line 140 — an earlier startup step, a retried init block, or duplicated code calling set_preview_proxy_port twice in one process.
Common situations: Refactoring startup so proxy setup runs in a retry loop; separate dev and prod code paths both configuring the proxy port; merging patches that each added the call; wrapping the init sequence in a function invoked more than once.
Related errors
- client server address already set
- Failed to load orchestrator MCP context from /api/containers
- no OAuth providers configured
- Migration failed: {}
- Container ref not found
AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29).
Data as JSON: /api/errors/23c8fd081b278b39.
Report an issue: GitHub.