---
title: "Stack Trace Rules"
description: "Learn how to use stack trace rules to group incoming events based on matchers."
url: https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules/
---

# Stack Trace Rules

This feature is only applicable for [error issues](https://docs.sentry.io/product/issues/issue-details/error-issues.md). Other categories of issues (such as [performance issues](https://docs.sentry.io/product/issues/issue-details/performance-issues.md) or [replay issues](https://docs.sentry.io/product/issues/issue-details/replay-issues.md)) do not support this feature.

Stack trace rules improve issue tracking by ensuring accurate grouping and better classification of stack frames as in-app or system. This helps focus on relevant code, reduces noise, and minimizes false positives. By tailoring rules to your project, you can streamline debugging and maintain consistency across teams or multiple applications.

When you set stack trace rules (previously known as *grouping enhancements*) for grouping in Sentry, they influence the data that's fed into the grouping algorithm. These rules can be configured on a per-project basis in your project's [Issue Grouping](https://sentry.io/orgredirect/organizations/:orgslug/settings/projects/:projectId/issue-grouping/) settings.

Here are a few things to note about stack trace rules:

* Each rule is written on a single line.
* Rules consist of one or more match expressions followed by one or more actions triggered when all expressions match.
* Rules are applied sequentially, from top to bottom, across all frames in the stack trace.

In addition, the stack trace rules using the below matchers and actions can also be applied to incoming profiles to improve frame classification (in-app vs system, for example).

Allowed Matchers:

* `stack.abs_path`
* `stack.module`
* `stack.function`
* `stack.package`

Allowed Actions:

* `+app`
* `-app`

The syntax for stack trace rules is similar to:

```bash
matcher-name:expression other-matcher:expression ... action1 action2 ...
```

If you want to negate the match, prefix the expression with an exclamation mark (`!`). If a line is prefixed with a hash (`#`), it's ignored and treated as a comment.

The following is a practical example of how this looks:

```bash
# mark all functions in the std namespace to be outside the app
family:native stack.function:std::*       -app

# mark all code in node modules not to be in app
stack.abs_path:**/node_modules/**         -app

# remove all generated javascript code from all grouping
stack.abs_path:**/generated/**.js         -group
```

## [Matchers](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#matchers)

Multiple matchers can be defined in a line. The following matchers are available:

### [`family`](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#family)

Matches on the general platform family, which currently includes `javascript`, `native` and `other`. Comma separate rules to apply them to multiple platforms.

```bash
family:javascript,native stack.abs_path:**/generated/**  -group
```

### [`stack.abs_path`](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#stackabs_path)

alias: `path`

This matcher is case insensitive with Unix glob behavior on a path in a stack trace. The path separators are normalized to `/`. As a special rule, if the filename is relative, it still matches on `**/`.

```bash
# match on all files under `project` with a `.c` extension
stack.abs_path:**/project/**.c +app

# matches on vendor/foo without sub folders
stack.abs_path:**/vendor/foo/*.c -app

# matches on `foo.gen.c` as well as `foo/bar.gen.c`.
stack.abs_path:**/*.gen.c -group
```

### [`stack.module`](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#stackmodule)

alias: `module`

Module is similar to `path` but matches on the `module`. This is not used for Native but it is used for JavaScript, Python, and similar platforms. Matches are case-sensitive, and normal globbing is available. Note that modules are not packages, which can be confusing for Native environments.

### [`stack.function`](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#stackfunction)

alias: `function`

Matches on a function in a stack trace, and is case-sensitive with normal globbing.

```bash
stack.function:myproject_* +app
stack.function:malloc      -group
```

### [`stack.package`](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#stackpackage)

alias: `package`

Matches on a package in a stack trace. The package is the container that contains a function or module. This is a `.jar`, a `.dylib` or similar. The same matching rules as for `path` apply. For example, this is typically an absolute path.

```bash
stack.package:**/libcurl.dylib -group
```

### [`app`](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#app)

Matches on the current state of the in-app flag of a stack trace frame. `yes` means the frame is in-app, `no` means it's not.

### [`category`](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#category)

Matches on a [built-in](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#built-in-categories) or a user-defined frame category. See [variable actions](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#variable-actions) on how to set a category.

```bash
category:telemetry -group
```

#### [Built-in Categories](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#built-in-categories)

Frame categorization is heavily used by our newest grouping algorithm. You can match on a variety of categories, including:

* `system` - detected system libraries
* `std` - detected standard libraries
* `ui` - UI frameworks
* `driver` - graphics drivers, and so on
* `telemetry` - crash reporting and analytics frameworks

See [our source code](https://github.com/getsentry/sentry/blob/master/src/sentry/grouping/enhancer/enhancement-configs/mobile%402021-04-02.txt) for a full list of built-in categories.

### [Matching Sibling Frames](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#matching-sibling-frames)

If information about the surrounding frames is necessary to apply a rule to a frame, use caller/callee matching syntax. For example:

```bash
# Ignore in-app frames if they are called by telemetry
[ category:telemetry ] | app:yes -group

# Ignore system frames if they call app frames
category:system | [ app:yes ] -group
```

## [Actions](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#actions)

There are two types of **actions**: flag and variables setting.

### [Flag Actions](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#flag-actions)

A *flag* identifies the action to be taken if all matchers match, and it uses these prefixes:

* `+` sets the flag
* `-` unsets the flag
* `^` applies to frames above the matching frame (toward the crash)
* `v` applies to frames below the matching frame (away from the crash)

As an example, `-group ^-group` removes the matching frame and all frames above it from the grouping.

* `app`: marks or unmarks a frame in-app
* `group`: adds or removes a frame from grouping

### [Variable Actions](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#variable-actions)

A limited set of *variables* can be defined (`variable=value`):

* `max-frames`: Sets the total number of frames to be considered for grouping. The default is `0`, which means "all frames". If set to `3`, only the top three frames are considered.

### [Example](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#example)

```bash
stack.abs_path:**/node_modules/** -group
stack.abs_path:**/app/utils/requestError.jsx -group
stack.abs_path:**src/getsentry/src/getsentry/** +app

family:native max-frames=3

stack.function:fetchSavedSearches v-group
stack.abs_path:**/app/views/**.jsx stack.function:fetchData ^-group

family:native stack.function:SpawnThread v-app -app
family:native stack.function:_NSRaiseError ^-group -app
family:native stack.function:std::* -app
family:native stack.function:core::* -app
```

## [Recommendations](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#recommendations)

These recommendations will greatly improve your out-of-the-box grouping experience.

### [Mark in-app Frames](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#mark-in-app-frames)

To proactively improve your experience, help Sentry determine which frames in your stack trace are "in-app" (part of your own application) and which are not. The SDK defines the default rules, but in many cases, this can be improved on the server as well. In particular, for languages where server-side processing is necessary (for example, Native C, C++, or JavaScript), it's better to override this on the server.

For instance, the following marks all frames that are below a specific C++ namespace are in-app:

```bash
stack.function:myapplication::* +app
```

See [in-app frames for Apple](https://docs.sentry.io/platforms/apple/usage/in-app-frames.md) to find out how the `sentry-cocoa` SDK marks frames as in-app.

#### [Stack Trace Rules](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#stack-trace-rules)

The following marks frames from libdispatch starting with `_dispatch_` as `inApp`.

```bash
stack.function:_dispatch_*  +app
```

You can also achieve the same result by marking other frames "not in-app." However, if that's the case, you should ensure that first all frames are set to "in-app" to override the defaults:

```bash
app:no                   +app
stack.function:std::*    -app
stack.function:boost::*  -app
```

You need to force all frames to be in-app first because there might already have been some defaults set by the client SDK or earlier processing.

If you're using the `sentry-cocoa` SDK, you can also achieve the same result by marking other frames `not inApp`. The following sample marks functions from the classes `DataRequest` and `DownloadRequest` as `not inApp`.

```bash
stack.function:DataRequest*  -app
stack.function:DownloadRequest*  -app
```

### [Cut Stack Traces](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#cut-stack-traces)

In many cases, you want to remove the top or bottom of the stack trace. For instance, many code bases use a common function to generate an error. In this case, the error machinery will appear as part of the stack trace.

For example, if you use Rust, you likely want to remove some frames that are related to panic handling:

```bash
stack.function:std::panicking::begin_panic       ^-app -app ^-group -group
stack.function:core::panicking::begin_panic      ^-app -app ^-group -group
```

Here we tell the system that all frames from `begin-panic` to the crash location are not part of the application (including the panic frame itself). All frames above are, in all cases, irrelevant for grouping.

Likewise, you can also remove the base of a stack trace. This is particularly useful if you have different main loops that drive an application:

```bash
stack.function:myapp::LinuxMainLoop         v-group -group
stack.function:myapp::MacMainLoop           v-group -group
stack.function:myapp::WinMainLoop           v-group -group
```

### [Stack Trace Frame Limits](https://docs.sentry.io/concepts/data-management/event-grouping/stack-trace-rules.md#stack-trace-frame-limits)

This isn't useful for *all* projects, but it can work well for large applications with many crashes. The default strategy is to consider most of the stack trace relevant for grouping. This means that every different stack trace that leads to a crashing function will cause a different group to be created. If you do not want that, you can force the groups to be much larger by limiting how many frames should be considered.

For instance, if any of the frames in the stack trace refer to a common external library, you could tell the system only to consider the top N frames:

```bash
# always only consider the top 1 frame for all native events
family:native max-frames=1

# if the bug is in proprietarymodule.so, only consider top 2 frames
family:native stack.package:**/proprietarymodule.so  max-frames=2

# these are functions we want to consider much more of the stack trace for
family:native stack.function:KnownBadFunction1  max-frames=5
family:native stack.function:KnownBadFunction2  max-frames=5
```
