rust-lang/cargo · error
unexpected variable ` ` in resolver.lockfile-path
Error message
unexpected variable `{variable}` in resolver.lockfile-path `{raw_template}` What it means
Cargo resolves `resolver.lockfile-path` (from config) as a templated path via `resolve_templated_path`. The replacements map is currently empty (`[(&str, &str); 0] = []`), so no variables are supported. If the template contains a `{variable}` token that is not in the (empty) replacement map, `ResolveTemplateError::UnexpectedVariable` is raised and wrapped into this anyhow error naming both the unknown variable and the raw template string.
Solutions
- Use a literal, fully-specified file path for `resolver.lockfile-path` ending in `Cargo.lock` (the code later requires `path.ends_with(LOCKFILE_NAME)`).
- Remove any `{...}` template tokens from the lockfile-path value, since no variables are currently substituted.
- If you need path relativization across workspace roots, compute the absolute path externally and set the literal result.
Example fix
# before
[resolver]
lockfile-path = "{workspace}/Cargo.lock"
# after
[resolver]
lockfile-path = "./Cargo.lock" Defensive patterns
Strategy: validation
Validate before calling
use regex::Regex;
fn has_brace_token(s: &str) -> bool {
Regex::new(r"\{[^}]*}").unwrap().is_match(s)
}
let lp: String = /* resolver.lockfile-path */;
assert!(!has_brace_token(&lp), "lockfile-path supports no variables"); Prevention
- Treat `resolver.lockfile-path` as a literal path; never insert `{...}` tokens.
- Ensure the value ends with `Cargo.lock`.
- Lint config files for brace tokens in keys known to accept no templates.
When it happens
Trigger: Setting `resolver.lockfile-path` to a string containing a brace-delimited token such as `{workspace}` or `{target}` in `.cargo/config.toml`, then triggering workspace lockfile path resolution. Because the replacements array is empty, every brace-token is unexpected.
Common situations: Assuming lockfile-path supports the same template variables as `build.build-dir`; copying templating syntax from docs/examples that target a different Cargo feature; using `${...}`-style or `{...}`-style placeholders expecting expansion.
Related errors
- unexpected bracket ` ` in build.build-dir path
- can't find library ` `, rename file to `src/lib.rs` or…
- cannot mix `proc-macro` crate type with others
- cannot specify both `metabuild` and `build`
- config.json not found
AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11).
Data as JSON: /api/errors/87d729603d997968.
Report an issue: GitHub.
Appendix: source
Thrown at src/workspace/workspace.rs:366
.feature_unification
.unwrap_or(FeatureUnification::Selected);
} else if config.feature_unification.is_some() {
self.gctx()
.shell()
.warn("ignoring `resolver.feature-unification` without `-Zfeature-unification`")?;
};
if let Some(lockfile_path) = config.lockfile_path {
// Reserve the ability to add templates in the future.
let replacements: [(&str, &str); 0] = [];
let path = lockfile_path
.resolve_templated_path(self.gctx(), replacements)
.map_err(|e| match e {
context::ResolveTemplateError::UnexpectedVariable {
variable,
raw_template,
} => {
anyhow!(
"unexpected variable `{variable}` in resolver.lockfile-path `{raw_template}`"
)
}
context::ResolveTemplateError::UnexpectedBracket { bracket_type, raw_template } => {
let (btype, literal) = match bracket_type {
context::BracketType::Opening => ("opening", "{"),
context::BracketType::Closing => ("closing", "}"),
};
anyhow!(
"unexpected {btype} bracket `{literal}` in build.build-dir path `{raw_template}`"
)
}
})?;
if !path.ends_with(LOCKFILE_NAME) {
bail!("the `resolver.lockfile-path` must be a path to a {LOCKFILE_NAME} file");
}
if path.is_dir() {View on GitHub (pinned to 98a09e7e7d)