stamparm/maltrail · warning

lookahead should match

Error message

lookahead should match

What it means

In the fancy-regex engine test `fancy_handles_lookahead`, `re.captures(...)` returns `Result<Option<Captures>>` and the test `.unwrap()`s the `Result` then `.expect("lookahead should match")`s the `Option`. The panic asserts the pattern `(?P<high>malware(?! (distribution|site)))|(?P<low>reputation)` matches 'known malware c2' via the `high` group; failure means the engine no longer handles named-group alternation with negative lookahead.

Solutions

  1. First test the pattern with a standalone fancy-regex instance (`Regex::new` + `captures`) to isolate whether the bug is in the engine or in `build_fancy`'s pattern rewriting.
  2. Print the rewritten pattern from `build_fancy` and verify the named groups and `(?! ...)` lookahead survive translation intact.
  3. Check the engine version's lookahead support; if the backend changed, fix lowering of negative lookahead so a non-matching suffix does not suppress the whole alternation branch.
  4. Split the test: assert `is_match` before asserting group captures, so match-failure and group-extraction regressions are distinguishable.

Example fix

// before
let hit = re.captures("known malware c2").unwrap().expect("lookahead should match");
// after (diagnose which stage failed)
let hit = re.captures("known malware c2")
    .expect("captures returned Err")
    .unwrap_or_else(|| panic!("no match for 'known malware c2' with pattern {}", re.as_str()));
Defensive patterns

Strategy: validation

Validate before calling

// verify the pattern compiles and matches before asserting groups
assert!(re.is_match("known malware c2"), "pattern lost lookahead semantics");

Try / catch

let hit = re.captures("known malware c2")
    .expect("captures Err")
    .unwrap_or_else(|| panic!("no match; pattern={}", re.as_str()));

Prevention

When it happens

Trigger: `build_fancy(...).captures("known malware c2")` returns `Ok(None)` (no match) or `Err` (regex compile/exec error), panicking at the expect. Triggered by regressions in the fancy regex backend: broken negative-lookahead semantics (over-suppressing), named-capture alternation bugs, or `build_fancy` compiling the pattern incorrectly.

Common situations: Upgrading or swapping the regex engine backing `build_fancy`; changes to the lookahead lowering/compilation; pattern-rewrite logic that mangles `(?P<name>...)` groups inside alternations; test refactor altering the sample text.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of stamparm/maltrail@77cfb06d76 (2026-09-13). Data as JSON: /api/errors/d41e6382e91f0042. Report an issue: GitHub.

Appendix: source

Thrown at sensor/src/pyre.rs:364

        // a leading flag group is fine, and scoped flags are fine anywhere
        assert!(!has_late_global_flags(r"(?i)abc"));
        assert!(!has_late_global_flags(r"a(?i:b)c"));
        assert!(!has_late_global_flags(r"a(?P<n>b)c"));
        assert!(!has_late_global_flags(r"a(?!b)c"));
        assert!(!has_late_global_flags(r"a\(?i\)b"));
    }

    #[test]
    fn punctuation_escapes_the_crate_dislikes_still_compile() {
        // from data/ua.txt: Python treats \> as a literal '>'
        let re = build(r"<script src=[^\>]*>").unwrap();
        assert!(re.is_match("<script src=x>"));
    }

    #[test]
    fn fancy_handles_lookahead() {
        let re = build_fancy(r"(?P<high>malware(?! (distribution|site)))|(?P<low>reputation)").unwrap();
        let hit = re.captures("known malware c2").unwrap().expect("lookahead should match");
        assert!(hit.name("high").is_some());
        // the negative lookahead suppresses the match entirely here
        assert!(matches!(re.captures("malware distribution"), Ok(None)));
        assert!(re.captures("reputation x").unwrap().unwrap().name("low").is_some());
    }
}

View on GitHub (pinned to 77cfb06d76)