jdx/mise · error

unclosed brace alternate in glob pattern {pattern:?}

Error message

unclosed brace alternate in glob pattern {pattern:?}

What it means

After scanning the whole glob pattern, find_group checks that every `{` opened a brace alternate was closed by a `}`. If group_depth is non-zero at end of input, an alternate was left open and the function bails with the offending pattern. This prevents partial/incorrect brace expansion of task globs.

Source

Thrown at src/task/task_source_checker.rs:137

                        if let Some(mut nested) = find_group(&pattern[start + 1..idx])? {
                            let offset = start + 1;
                            nested.start += offset;
                            nested.end += offset;
                            for (branch_start, branch_end) in &mut nested.branches {
                                *branch_start += offset;
                                *branch_end += offset;
                            }
                            return Ok(Some(nested));
                        }
                        group_start = None;
                        branches.clear();
                    }
                }
                _ => {}
            }
        }
        if group_depth != 0 {
            bail!("unclosed brace alternate in glob pattern {pattern:?}");
        }
        Ok(None)
    }

    fn expand(pattern: &str, expanded: &mut Vec<String>) -> Result<()> {
        let Some(group) = find_group(pattern)? else {
            if expanded.len() >= MAX_BRACE_EXPANSIONS {
                bail!(
                    "glob pattern expands to more than {MAX_BRACE_EXPANSIONS} alternatives: {pattern:?}"
                );
            }
            let mut literal = String::with_capacity(pattern.len());
            let mut escaped = false;
            let mut class_depth = 0;
            for ch in pattern.chars() {
                if escaped {
                    escaped = false;
                    literal.push(ch);

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Close the brace alternate with the matching `}` in the pattern
  2. Split an overly complex pattern into multiple simpler entries
  3. Escape literal `{` as `\{` if brace expansion was not intended

Example fix

// before
outputs = ['dist/{js,css/*.map']
// after
outputs = ['dist/{js,css}/*.map']
Defensive patterns

Strategy: validation

Validate before calling

// js: ensure every '{' in a task glob has a matching '}'
function hasClosedBraces(p) {
  let d = 0;
  for (const ch of p.replace(/\\./g, '')) {
    if (ch === '{') d++;
    if (ch === '}') d--;
  }
  return d === 0;
}
hasClosedBraces('dist/{js,css}/*.map'); // true

Prevention

When it happens

Trigger: Supplying a task glob with an unterminated `{` group, e.g. `src/{a,b/*.ts`, via sources/outputs or file patterns processed by expand_glob_braces.

Common situations: Typo when writing multi-branch globs in mise.toml; a line got truncated when editing config; nested braces written for another glob flavor that mise doesn't parse the same way.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/41baa48c7ea32ddb. Report an issue: GitHub.