jdx/mise · error
valid Homebrew version token pattern
Error message
valid Homebrew version token pattern
What it means
A static `Regex::new(...).expect("valid Homebrew version token pattern")` panic. The pattern is compiled once via `LazyLock`; a panic here can only mean the hard-coded Homebrew version token regex failed to compile — normally impossible unless the source pattern was edited incorrectly.
Solutions
- Fix the regex syntax so it compiles (count capture groups, close all parens)
- Run a unit test that touches compare_app_versions so compilation happens in CI
- Temporarily replace expect with a panic-free constructor during regex experimentation
Example fix
// before "(?i:(alpha[0-9]*|a[0-9]+|(beta[0-9]*|b[0-9]+)|..." // after "(?i:(alpha[0-9]*|a[0-9]+)|(beta[0-9]*|b[0-9]+)|(pre[0-9]*)|..."
Defensive patterns
Strategy: try-catch
Validate before calling
// compile-time-ish check in a test
#[test] fn token_regex_compiles() {
LazyLock::force(&PATTERN);
} Prevention
- Never edit the static regex without running a test that calls tokens()
- Keep capture-group structure documented next to the pattern
- Let CI compile the LazyLock via a unit test
When it happens
Trigger: Calling `tokens()` (via `compare_app_versions`) on any version string the first time, after someone modified the hard-coded regex in src/system/packages/brew/cask/app_version.rs:234 so it is syntactically invalid (e.g. unbalanced groups).
Common situations: Editing the regex during development; platform regex-engine differences if the pattern is ported; merging conflicting regex changes.
Related errors
- each version token has one matching kind
- every selected bottle was prepared
- ruby-build version regex
- static credential globs
- a provided source resolves to a path
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/e1e823ff0a60bf31.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/packages/brew/cask/app_version.rs:234
}
/// Compares ASCII digit strings without integer overflow, ignoring leading zeros.
/// Empty strings represent zero.
fn compare_digits(a: &str, b: &str) -> Ordering {
let a = a.trim_start_matches('0');
let b = b.trim_start_matches('0');
a.len().cmp(&b.len()).then_with(|| a.cmp(b))
}
/// Extracts numeric, qualifier, and text tokens using Homebrew's version pattern.
/// Qualifier recognition is case-insensitive; token text retains its original case.
fn tokens(version: &str) -> Vec<Token<'_>> {
static PATTERN: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(concat!(
"(?i:(alpha[0-9]*|a[0-9]+)|(beta[0-9]*|b[0-9]+)|(pre[0-9]*)|",
"(rc[0-9]*)|(p[0-9]*)|(.post[0-9]+)|([0-9]+)|([a-z]+))"
))
.expect("valid Homebrew version token pattern")
});
let kinds = [
TokenKind::Alpha,
TokenKind::Beta,
TokenKind::Pre,
TokenKind::Rc,
TokenKind::Patch,
TokenKind::Post,
TokenKind::Numeric,
TokenKind::Text,
];
PATTERN
.captures_iter(version)
.map(|captures| {
let (kind, text) = kinds
.iter()
.enumerate()
.find_map(|(index, kind)| {View on GitHub (pinned to 533346cc37)