rust-lang/cargo · error

unexpected {btype} bracket `{literal}` in build.build-dir pa

Error message

unexpected {btype} bracket `{literal}` in build.build-dir path `{raw_template}`

What it means

While resolving `build.build-dir`, if resolve_templated_path encounters an unbalanced brace (an opening `{` with no closing `}` or a stray `}`), it returns UnexpectedBracket and Cargo bails 'unexpected <opening|closing> bracket `{`|`}` in build.build-dir path `<template>`' (mod.rs:814-823). The bracket_type maps to 'opening'/'closing' with the literal brace character.

Source

Thrown at src/context/mod.rs:820

                    variable,
                    raw_template,
                } => {
                    let mut suggestion = closest_msg(&variable, template_variables.iter(), |key| key, "template variable");
                    if suggestion == "" {
                        let variables = template_variables.iter().map(|v| format!("`{{{v}}}`")).join(", ");
                        suggestion = format!("\n\nhelp: available template variables are {variables}");
                    }
                    anyhow!(
                            "unexpected variable `{variable}` in build.build-dir path `{raw_template}`{suggestion}"
                        )
                }
                path::ResolveTemplateError::UnexpectedBracket { bracket_type, raw_template } => {
                    let (btype, literal) = match bracket_type {
                        path::BracketType::Opening => ("opening", "{"),
                        path::BracketType::Closing => ("closing", "}"),
                    };

                    anyhow!(
                            "unexpected {btype} bracket `{literal}` in build.build-dir path `{raw_template}`"
                        )
                }
            })?;

        // Check if the target directory is set to an empty string in the config.toml file.
        if val.raw_value().is_empty() {
            bail!(
                "the build directory is set to an empty string in {}",
                val.value().definition
            )
        }

        Ok(Filesystem::new(path))
    }

    /// Get a configuration value by key.
    ///

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Balance every `{` with a `}` in the build-dir template.
  2. Remove unintended braces so the path is a plain literal.
  3. Re-read the message: it shows the exact raw template that failed.

Example fix

# before (.cargo/config.toml)
[build]
build-dir = "/cache/{workspace-path-hash/target"  # missing }
# after
[build]
build-dir = "/cache/{workspace-path-hash}/target"
Defensive patterns

Strategy: validation

Validate before calling

# Check build-dir braces are balanced:
python3 - <<'EOF'
import tomllib
try:
    d = tomllib.load(open('.cargo/config.toml','rb'))
except FileNotFoundError: raise SystemExit(0)
bd = d.get('build',{}).get('build-dir')
if bd:
    assert bd.count('{') == bd.count('}'), 'unbalanced braces in build-dir'
EOF

Prevention

When it happens

Trigger: A build-dir value with a stray or unmatched brace, e.g. `build-dir = "/x/{workspace-root}` (missing close) or a template that opens a variable but never closes it.

Common situations: Hand-editing config.toml and dropping a `}`; copy-paste truncation; intending a literal brace but using the template syntax.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/303faacfe9bb1c75.json. Report an issue: GitHub.