Skip to content

fix(classify): do not crash on invalid user-supplied regex - #148

Open
fanxing11 wants to merge 1 commit into
ActivityWatch:masterfrom
fanxing11:fix/classify-invalid-regex-graceful
Open

fix(classify): do not crash on invalid user-supplied regex#148
fanxing11 wants to merge 1 commit into
ActivityWatch:masterfrom
fanxing11:fix/classify-invalid-regex-graceful

Conversation

@fanxing11

Copy link
Copy Markdown
Contributor

Small drive-by fix for ActivityWatch/activitywatch#1340.

What happened

Rule.__init__ (in aw_transform/classify.py) compiles user-supplied
regex patterns eagerly with re.compile(...). If the pattern is
invalid, re.error is raised straight out of __init__, bubbles up
through the query engine, and aw-server responds with 500 Internal
Server Error
for the whole query. The web UI then shows nothing for
any categorize()/tag() chart, not just the rule that was broken.

The reproducer in the issue is Notepad++ (the user probably wanted
Notepad\+\+). On Python <= 3.10 this raises re.error: multiple repeat at position 8. On 3.11+ ++ happens to be a valid possessive
quantifier so that particular pattern no longer breaks, but the class
of bug still exists: any user typo like *foo or (unclosed will
take down the whole categorize query.

Fix

Catch re.error in Rule.__init__, log a warning, and set self.regex = None so that rule matches nothing. Other rules keep working;
events that would have matched the broken rule fall through to
Uncategorized instead of tanking the query. The webui can still
provide inline validation on top of this later, but the server should
not 500 on user input.

Tests

Added two tests in tests/test_transforms.py:

  • test_rule_invalid_regex_does_not_raise — invalid pattern gives
    regex=None, match(event) returns False.
  • test_categorize_survives_invalid_regex — a bad rule mixed with a
    good rule: good rule still categorizes, unrelated events go to
    Uncategorized (instead of the whole call raising).

Existing test_categorize / test_tags unchanged and still pass.

Fixes ActivityWatch/activitywatch#1340

Rule.__init__ used to bubble up re.error from re.compile() when a
user saved an invalid regex pattern in the category editor
(e.g. "Notepad++" on Python versions where "++" is not a valid
possessive quantifier). aw-server then returned 500 Internal Server
Error for the whole query, which broke every categorize()/tag() chart
in the web UI, not just the offending rule.

Catch re.error at compile time, log a warning, and disable that one
rule (regex=None, match always False). Other rules keep working and
events that would have matched the broken rule show up as
"Uncategorized" instead of crashing the whole query.

Fixes ActivityWatch/activitywatch#1340
Comment thread aw_transform/classify.py
regex_str,
(re.IGNORECASE if self.ignore_case else 0) | re.UNICODE,
)
except re.error as e:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Non-string regex errors escape

When a categorize or tag rule contains a truthy non-string regex value such as 123, re.compile raises TypeError, which bypasses this handler and still aborts the entire query with an internal server error.

Suggested change
except re.error as e:
except (re.error, TypeError) as e:

@greptile-apps

greptile-apps Bot commented Jul 28, 2026

Copy link
Copy Markdown

Greptile Summary

This PR prevents syntactically invalid string regexes from aborting classification queries.

  • Catches re.error while compiling category and tag rules.
  • Logs invalid patterns and disables those rules so other rules continue matching.
  • Adds direct and categorization-level regression tests.

Confidence Score: 3/5

The PR should not merge until malformed non-string regex values are prevented from escaping the new recovery path and aborting classification queries.

The change handles re.error correctly for malformed strings, but reachable query dictionaries can contain truthy non-string regex values for which re.compile raises an uncaught TypeError.

Files Needing Attention: aw_transform/classify.py

Important Files Changed

Filename Overview
aw_transform/classify.py Adds graceful handling for regex syntax errors, but truthy non-string rule values still escape as TypeError and abort the query.
tests/test_transforms.py Covers invalid regex syntax and mixed good/bad rules, but does not cover malformed non-string regex values accepted by the query representation.

Reviews (1): Last reviewed commit: "fix(classify): do not crash on invalid u..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"++" in Category Pattern leads to internal Server Error

1 participant