{"id":"0e23def644f66ad2","repo":"rust-lang/cargo","slug":"already-loaded-config-values","errorCode":null,"errorMessage":"already loaded config values","messagePattern":"already loaded config values","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/context/mod.rs","lineNumber":657,"sourceCode":"\n    /// Gets all config values from disk.\n    ///\n    /// This will lazy-load the values as necessary. Callers are responsible\n    /// for checking environment variables. Callers outside of the `config`\n    /// module should avoid using this.\n    pub fn values(&self) -> CargoResult<&HashMap<String, ConfigValue>> {\n        self.values.try_borrow_with(|| self.load_values())\n    }\n\n    /// Gets a mutable copy of the on-disk config values.\n    ///\n    /// This requires the config values to already have been loaded. This\n    /// currently only exists for `cargo vendor` to remove the `source`\n    /// entries. This doesn't respect environment variables. You should avoid\n    /// using this if possible.\n    pub fn values_mut(&mut self) -> CargoResult<&mut HashMap<String, ConfigValue>> {\n        let _ = self.values()?;\n        Ok(self.values.get_mut().expect(\"already loaded config values\"))\n    }\n\n    // Note: this is used by RLS, not Cargo.\n    pub fn set_values(&self, values: HashMap<String, ConfigValue>) -> CargoResult<()> {\n        if self.values.get().is_some() {\n            bail!(\"config values already found\")\n        }\n        match self.values.set(values.into()) {\n            Ok(()) => Ok(()),\n            Err(_) => bail!(\"could not fill values\"),\n        }\n    }\n\n    /// Sets the path where ancestor config file searching will stop. The\n    /// given path is included, but its ancestors are not.\n    pub fn set_search_stop_path<P: Into<PathBuf>>(&mut self, path: P) {\n        let path = path.into();\n        debug_assert!(self.cwd.starts_with(&path));","sourceCodeStart":639,"sourceCodeEnd":675,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/context/mod.rs#L639-L675","documentation":"This panic is in GlobalContext::values_mut(), which cargo vendor uses to mutate loaded config values. The method first calls self.values() (which lazy-loads config from disk via a OnceCell), then calls .get_mut() on that cell expecting it to now be filled. If the OnceCell's internal state is inconsistent — filled() reported true inside values() but get_mut() returns None — the expect fires.","triggerScenarios":"Calling values_mut() without having previously called values() or load_values() successfully, or in a context where the OnceCell was reset/cleared between the borrow check and the get_mut call. In practice this path is only exercised by cargo vendor when stripping [source] entries.","commonSituations":"Running cargo vendor with a manually corrupted or partially-written config file; using cargo as a library and calling values_mut() after set_values() failed; a re-entrant config access pattern that resets the cell.","solutions":["Call ctx.values() explicitly first to ensure config is loaded before calling values_mut().","Check that config files are valid TOML and readable before attempting mutation.","Avoid calling values_mut() from multiple threads — it requires &mut self so this should be impossible, but verify no unsafe aliasing exists in library embedding."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure values are loaded before calling values_mut()\nlet _ = ctx.values()?; // triggers lazy load\n// now safe to mutate\nlet values = ctx.values_mut()?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always call ctx.values() before ctx.values_mut() to ensure the OnceCell is populated.","Validate config files are readable and valid TOML before mutation operations.","Avoid re-entrant config access patterns in library embedding."],"tags":["rust","cargo","panic","invariant","config","cargo-vendor"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}