AlexsJones/llmfit · info

valid MLX suffix regex

Error message

valid MLX suffix regex

What it means

An .expect() panic string in strip_mlx_quant_suffix (llmfit-core/src/providers.rs). OnceLock lazily compiles the hardcoded regex -\d+bit(?:-[a-z0-9]+)*$; Regex::new only fails on an invalid pattern, and this literal is a fixed, tested constant. The expect can therefore only fire if someone edits the pattern into an invalid regex — it is an internal-invariant assertion (per repo convention), not a runtime error users can trigger.

Solutions

  1. Revert or fix the regex literal in providers.rs to a valid pattern (e.g. the original r"-\d+bit(?:-[a-z0-9]+)*$")
  2. Run `cargo test -p llmfit-core providers` after touching the pattern to catch compile-time regex breakage in CI
Defensive patterns

Strategy: validation

Validate before calling

// CI/test guard: fail early if the MLX suffix pattern is edited into an invalid regex
#[test]
fn mlx_suffix_regex_compiles() {
    assert!(regex::Regex::new(r"-\d+bit(?:-[a-z0-9]+)*$").is_ok());
    assert_eq!(strip_mlx_quant_suffix("qwen3-4bit").as_deref(), Some("qwen3"));
}

Prevention

When it happens

Trigger: A contributor changes the pattern string (e.g. introduces an unescaped '(' or mismatched brace) and the first call to strip_mlx_quant_suffix for a stem without the -mxfp4/-fp16 suffixes panics at regex compile time.

Common situations: Editing the MLX suffix rules without running the unit tests that exercise this function; cargo test suites that cover providers.rs would catch it before merge.

Related errors


AI-assisted analysis of AlexsJones/llmfit@1e7bdb3ecf (2026-08-17). Data as JSON: /api/errors/95297f8b128374da. Report an issue: GitHub.

Appendix: source

Thrown at llmfit-core/src/providers.rs:3774

            // part of the canonical model name, so strip it too — otherwise the
            // stem never reduces to the catalog id and the file reads as neither
            // installed nor served.
            let base = base.strip_suffix("-ud").unwrap_or(base);
            return Some(base.to_string());
        }
    }
    None
}

/// Strip an MLX quantization suffix from a lowercased model stem, so
/// mlx-community basenames reduce to catalog slugs (#854, #869).
/// "llama-3.2-1b-instruct-4bit" → "llama-3.2-1b-instruct"
///
/// End-anchored, unlike the GGUF list above: mlx-community always places the
/// quant scheme last, and dtype-like fragments can occur inside genuine model
/// names. Strips, in order: the quant scheme (`-<N>bit` or `-mxfp4`, each
/// with optional trailing variant markers such as `-4bit-dwq`, date-stamped
/// `-4bit-dwq-05082025`, `-mxfp4-q8`, `-mxfp4-bf16`, or a plain `-fp16`),
/// then a trailing `-mlx` marker (`...-instruct-mlx-8bit` → `...-instruct`).
///
/// Returns `None` when nothing was stripped, so lookup callers can tell "no
/// MLX suffix present" apart from "already reduced".
pub fn strip_mlx_quant_suffix(stem: &str) -> Option<String> {
    static MLX_QUANT_SUFFIX: OnceLock<Regex> = OnceLock::new();
    let re = MLX_QUANT_SUFFIX.get_or_init(|| {
        Regex::new(r"-(?:\d+bit(?:-[a-z0-9]+)*|mxfp4(?:-[a-z0-9]+)*|fp16)$")
            .expect("valid MLX suffix regex")
    });
    let without_quant = match re.find(stem) {
        Some(m) if m.start() > 0 => &stem[..m.start()],
        _ => stem,
    };
    let base = match without_quant.strip_suffix("-mlx") {
        Some(b) if !b.is_empty() => b,
        _ => without_quant,
    };

View on GitHub (pinned to 1e7bdb3ecf)