{"record":{"id":"23c8fd081b278b39","repo":"BloopAI/vibe-kanban","slug":"client-preview-proxy-port-already-set","errorCode":null,"errorMessage":"client preview proxy port already set","messagePattern":"client preview proxy port already set","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/server/src/main.rs","lineNumber":140,"sourceCode":"\n    if let Err(e) = write_port_file_with_proxy(actual_main_port, Some(actual_proxy_port)).await {\n        tracing::warn!(\"Failed to write port file: {}\", e);\n    }\n\n    tracing::info!(\n        \"Main server on :{}, Preview proxy on :{}\",\n        actual_main_port,\n        actual_proxy_port\n    );\n\n    deployment\n        .client_info()\n        .set_server_addr(main_listener.local_addr()?)\n        .expect(\"client server address already set\");\n    deployment\n        .client_info()\n        .set_preview_proxy_port(actual_proxy_port)\n        .expect(\"client preview proxy port already set\");\n\n    let app_router = routes::router(deployment.clone());\n\n    // Production only: open browser\n    if !cfg!(debug_assertions) {\n        tracing::info!(\"Opening browser...\");\n        let browser_port = actual_main_port;\n        tokio::spawn(async move {\n            if let Err(e) =\n                utils::browser::open_browser(&format!(\"http://127.0.0.1:{browser_port}\")).await\n            {\n                tracing::warn!(\n                    \"Failed to open browser automatically: {}. Please open http://127.0.0.1:{} manually.\",\n                    e,\n                    browser_port\n                );\n            }\n        });","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/BloopAI/vibe-kanban/blob/4deb7eca8f381f7cbc1f9d15515a9ab8f8009053/crates/server/src/main.rs#L122-L158","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ndeployment.client_info().set_preview_proxy_port(actual_proxy_port)\n    .expect(\"client preview proxy port already set\");\n// after\ndeployment.client_info().set_preview_proxy_port(actual_proxy_port)\n    .unwrap_or_else(|_| tracing::warn!(\"preview proxy port already set; ignoring\"));","handlingStrategy":"validation","validationCode":"if deployment.client_info().preview_proxy_port().is_none() {\n    deployment.client_info().set_preview_proxy_port(actual_proxy_port)?;\n}","typeGuard":null,"tryCatchPattern":"deployment.client_info()\n    .set_preview_proxy_port(actual_proxy_port)\n    .unwrap_or_else(|_| tracing::debug!(\"preview proxy port already configured\"));","preventionTips":["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."],"tags":["startup","initialization","invariant","proxy"],"backgroundTag":"already-initialized-once-cell","analyzedSha":"4deb7eca8f381f7cbc1f9d15515a9ab8f8009053","analyzedAt":"2026-08-29T09:24:13.446Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}