{"record":{"id":"219f4b697e2b7d98","repo":"cocoindex-io/cocoindex","slug":"with-base-url-must-be-called-before-the-connection","errorCode":null,"errorMessage":"with_base_url must be called before the connection is shared","messagePattern":"with_base_url must be called before the connection is shared","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"rust/sdk/cocoindex/src/turbopuffer.rs","lineNumber":71,"sourceCode":"    }\n\n    fn build(base_url: String, api_key: String, state_id: String) -> Self {\n        Self {\n            inner: Arc::new(ConnInner {\n                http: reqwest::Client::new(),\n                base_url: base_url.trim_end_matches('/').to_string(),\n                api_key,\n                state_id,\n            }),\n        }\n    }\n\n    /// Override the base URL (default `https://{region}.turbopuffer.com`). Mainly\n    /// for pointing at a mock server in tests.\n    pub fn with_base_url(mut self, base_url: impl Into<String>) -> Self {\n        let base_url = base_url.into().trim_end_matches('/').to_string();\n        let inner = Arc::get_mut(&mut self.inner)\n            .expect(\"with_base_url must be called before the connection is shared\");\n        inner.base_url = base_url;\n        self\n    }\n\n    /// Stable identity for use as a `ContextKey` state id / memo dep.\n    pub fn state_id(&self) -> &str {\n        &self.inner.state_id\n    }\n\n    async fn write(&self, namespace: &str, body: JsonValue) -> Result<()> {\n        let url = format!(\"{}/v2/namespaces/{namespace}\", self.inner.base_url);\n        self.inner\n            .http\n            .post(&url)\n            .bearer_auth(&self.inner.api_key)\n            .json(&body)\n            .send()\n            .await","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/rust/sdk/cocoindex/src/turbopuffer.rs#L53-L89","documentation":"TurboBuffer/ turbopuffer connection objects are shared via Arc; with_base_url() needs exclusive access (&mut via Arc::get_mut) to mutate the base URL. If the connection has already been cloned/shared (refcount > 1), Arc::get_mut returns None and the code panics. The API contract is: configure the URL before sharing the connection.","triggerScenarios":"Calling conn.with_base_url(\"http://localhost:8080\") after the connection was cloned, moved into a context/pool, or otherwise shared (Arc strong count > 1). Typical in tests that share one connection across setup code and then try to redirect it to a mock server.","commonSituations":"Test fixtures that create a connection, register/provide it somewhere, and then attempt to point it at a mock; storing the connection in a struct before finishing configuration.","solutions":["Reorder code: call .with_base_url() on the builder/connection before any clone or sharing.","Rebuild the connection with the desired base_url instead of mutating a shared one.","In tests, construct a fresh connection per scenario that needs a different base URL."],"exampleFix":"// before\nlet shared = conn.clone();\nconn.with_base_url(mock_url()); // panics\n\n// after\nlet conn = conn.with_base_url(mock_url());\nlet shared = conn.clone();","handlingStrategy":"validation","validationCode":"// configure before sharing\nlet conn = TurboConnection::new(region, creds)\n    .with_base_url(\"http://localhost:8080\");\nlet shared = std::sync::Arc::new(conn); // share only after config","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always finalize configuration (base URL, credentials) before cloning/sharing the connection.","In tests, build one connection per mock-server scenario instead of retargeting a shared one.","Treat connection objects as immutable after publication."],"tags":["rust","panic","arc","turbopuffer","test"],"backgroundTag":"invalid-state-transition","analyzedSha":"e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b","analyzedAt":"2026-09-08T15:59:19.997Z","contentChangedAt":"2026-09-08T15:59:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}