{"id":"dcf04f996d6ef87f","repo":"rust-lang/cargo","slug":"unexpected-btype-bracket-literal-in-build-bu-dcf04f","errorCode":null,"errorMessage":"unexpected {btype} bracket `{literal}` in build.build-dir path `{raw_template}`","messagePattern":"unexpected (.+?) bracket `(.+?)` in build\\.build-dir path `(.+?)`","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/workspace/workspace.rs","lineNumber":390,"sourceCode":"            let replacements: [(&str, &str); 0] = [];\n            let path = lockfile_path\n                    .resolve_templated_path(self.gctx(), replacements)\n                    .map_err(|e| match e {\n                        context::ResolveTemplateError::UnexpectedVariable {\n                            variable,\n                            raw_template,\n                        } => {\n                            anyhow!(\n                                \"unexpected variable `{variable}` in resolver.lockfile-path `{raw_template}`\"\n                            )\n                        }\n                        context::ResolveTemplateError::UnexpectedBracket { bracket_type, raw_template } => {\n                            let (btype, literal) = match bracket_type {\n                                context::BracketType::Opening => (\"opening\", \"{\"),\n                                context::BracketType::Closing => (\"closing\", \"}\"),\n                            };\n\n                            anyhow!(\n                                \"unexpected {btype} bracket `{literal}` in build.build-dir path `{raw_template}`\"\n                            )\n                        }\n                    })?;\n            if !path.ends_with(LOCKFILE_NAME) {\n                bail!(\"the `resolver.lockfile-path` must be a path to a {LOCKFILE_NAME} file\");\n            }\n            if path.is_dir() {\n                bail!(\n                    \"`resolver.lockfile-path` `{}` is a directory but expected a file\",\n                    path.display()\n                );\n            }\n            self.requested_lockfile_path = Some(path);\n        }\n\n        Ok(())\n    }","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/workspace/workspace.rs#L372-L408","documentation":"Raised in the same `resolve_templated_path` call (src/workspace/workspace.rs:384) when the lockfile-path contains an unmatched/unbalanced brace — `ResolveTemplateError::UnexpectedBracket` with `BracketType::Opening` (`{`) or `Closing` (`}`). The message reports whether the stray character is an opening or closing bracket and shows the raw template. Note the message string hard-codes 'build.build-dir path' even though it fires for `resolver.lockfile-path`.","triggerScenarios":"A `resolver.lockfile-path` value containing a lone `{` or `}` (e.g. `\"{Cargo.lock\"`, `\"dir/}x\"`, or a literal brace intended as a filename).","commonSituations":"Hand-editing config and leaving an unclosed brace; pasting a Windows path with brace characters; an editor auto-inserting a closing brace in the wrong place; shell variable leftovers like `${HOME}/Cargo.lock`.","solutions":["Balance or remove the stray `{` / `}` in the `resolver.lockfile-path` value.","If the brace was meant literally (rare), choose a path without brace characters.","Re-read the raw value from the config file the error references and fix it there."],"exampleFix":"# before\n[resolver]\nlockfile-path = \"${HOME}/Cargo.lock\"\n# after — use a real path, no shell/brace syntax\n[resolver]\nlockfile-path = \"/home/user/Cargo.lock\"","handlingStrategy":"validation","validationCode":"fn balanced_braces(s: &str) -> bool {\n    let mut depth = 0i32;\n    for c in s.chars() { match c { '{' => depth += 1, '}' => { depth -= 1; if depth < 0 { return false; } } _ => {} } }\n    depth == 0\n}\n// assert balanced_braces(&lockfile_path) and no stray braces","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid brace characters in resolver.lockfile-path entirely.","Do not put shell `${VAR}` syntax into cargo config."],"tags":["cargo","config","lockfile","template","syntax"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}