---
title: "Link frontend errors to GitHub commits | Grafana Cloud documentation"
description: "Configure Frontend Observability to link frontend errors in web apps to GitHub code and commits, using a reported commit hash and ranked stack-trace matching for additional candidates."
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# Link frontend errors to GitHub commits

The **Suspect Commits** feature in Frontend Observability helps you move from a frontend error to the GitHub code and commits that may have caused it. It can show:

- The commit where the error first appeared, when your app reports its Git commit hash.
- Ranked commits that changed paths in the error stack trace.

Commit-hash correlation is the recommended setup because it provides a direct signal from the app build. Stack-trace matching adds ranked candidates and can appear below the introducing commit when hash correlation succeeds.

This guide covers web apps. Setup requires Grafana Editor or administrator permissions. Other users can view the results after an Editor or administrator completes the setup.

> Note
> 
> The Faro Web SDK transmits the injected commit hash to Grafana Cloud as part of Faro telemetry and stores it with the error’s first-seen record. If you operate in a regulated industry or your repository is proprietary, review your organization’s data-handling policies before enabling this feature.

## Before you begin

You need:

- A web app instrumented with the [Faro Web SDK](/docs/grafana-cloud/observe-and-act/monitor-applications/frontend-observability/instrument/).
- A GitHub repository that contains the app code.
- Grafana Editor or administrator permissions to configure the app.
- An organization administrator who can install and configure the [GitHub data source](/docs/plugins/grafana-github-datasource/latest/configure/).

Source maps are not required for the introducing commit path. Upload source maps to enable stack-trace-based matching to app paths. Refer to [Upload source maps with bundlers](/docs/grafana-cloud/observe-and-act/monitor-applications/frontend-observability/configure/sourcemap-uploads/bundlers/).

## Configure the feature

Complete these steps in order.

**Minimum versions:**

- `@grafana/faro-web-sdk` and `@grafana/faro-react`: **2.7.0**
- `@grafana/faro-webpack-plugin`: **0.12.0**
- `@grafana/faro-rollup-plugin`: **0.11.0**
- `@grafana/faro-esbuild-plugin`: **0.6.0**
- `@grafana/faro-metro-plugin`: **0.2.0**
- `@grafana/faro-cli`: **0.10.0** for post-build injection

### Configure the GitHub data source

Follow the [GitHub data source configuration guide](/docs/plugins/grafana-github-datasource/latest/configure/). Use read-only GitHub access where possible and make sure the credentials can read the repository that contains your app code.

Use the **Save &amp; test** action in the GitHub data source settings. The connection must be working before you select it for an app.

### Select the GitHub data source for your app

1. In your Grafana stack, open **Frontend Observability**.
2. Open the web app that you want to configure.
3. Go to **Settings &gt; GitHub**.
4. In **GitHub connection**, select the GitHub data source that you configured earlier.
5. Enter the GitHub organization or user name in **Owner**.
6. Enter the repository name in **Repository name**.
7. Select **Save**.

The owner and repository must match the location of the app code. If your organization uses more than one GitHub data source, select the one that can access this repository. Frontend Observability does not choose a data source automatically.

### Upload source maps for stack-trace matching

Refer to [Upload source maps with bundlers](/docs/grafana-cloud/observe-and-act/monitor-applications/frontend-observability/configure/sourcemap-uploads/bundlers/) to configure the Webpack, Rollup/Vite, or `esbuild` integration for your build.

Source maps allow Frontend Observability to resolve an error stack trace to app paths. Keep the source map `appName`, `appId`, `stackId`, and bundle information aligned with the Faro Web SDK configuration used by the app.

After a build, verify the upload in **Frontend Observability &gt; your app &gt; Settings &gt; Source Maps**.

### Inject the Git commit hash into each build

Commit-hash correlation is the preferred setup because it records which build was running when the error first appeared. The Faro Web SDK sends the hash with telemetry, and Frontend Observability uses it to show the corresponding commit in the Suspect commits section.

The recommended option is to inject the hash with the [Faro bundler plugins](/docs/grafana-cloud/observe-and-act/monitor-applications/frontend-observability/configure/sourcemap-uploads/bundlers/). The plugins can inject the hash while they upload source maps. They use this priority order:

1. An explicit `gitHash` value passed to the plugin.
2. The result of `git rev-parse HEAD` in the build environment.

Use a full 40-character, lowercase hexadecimal commit SHA. If the explicit value does not match this format, the plugin falls back to `git rev-parse HEAD`. If neither value resolves, no hash is injected and the build still succeeds. The build log contains `[Faro] Git hash could not be resolved`.

Prefer an explicit `gitHash` value in continuous integration or multi-stage builds when the build environment does not contain the correct Git metadata. In GitHub Actions pull request builds, pass the pull request head SHA instead of a synthetic merge SHA when that is the commit you want to associate with the deployed build:

Pass the value to the plugin through its `gitHash` option. Setting an environment variable without using it in the plugin configuration has no effect:

JavaScript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```javascript
new FaroSourceMapUploaderPlugin({
  appName: '$your-app-name',
  endpoint: '$your-faro-sourcemap-api-url',
  gitHash: process.env.FARO_GIT_HASH,
});
```

YAML ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```yaml
- name: build
  env:
    FARO_GIT_HASH: ${{ github.event.pull_request.head.sha || github.sha }}
  run: yarn build
```

When `gitHash` is not specified, the plugin runs `git rev-parse HEAD` during the build. This works when the `.git` directory is available in the build context.

> Warning
> 
> Multi-stage Docker builds commonly exclude `.git` through `.dockerignore`, which causes auto-detection to fail. Set `gitHash` explicitly in that case.

#### Post-build injection with the Faro command-line tool

If you cannot run the bundler plugin at build time, use the Faro command-line tool to inject the hash into existing JavaScript artifacts:

Bash ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```bash
npx @grafana/faro-cli inject-git-hash \
  --app-name '$your-app-name' \
  --git-hash $(git rev-parse HEAD) \
  --files 'dist/**/*.js'
```

Refer to the [faro-JavaScript-bundler-plugins repository](https://github.com/grafana/faro-JavaScript-bundler-plugins) for the full command-line reference.

#### Set the commit hash in the Faro Web SDK configuration

If you do not use the Faro bundler plugins, set `app.gitHash` when initializing the Faro Web SDK. Because browsers do not have access to `process.env`, embed the commit SHA into the bundle at build time.

For local builds, make the SHA available to the build:

Bash ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```bash
export GIT_HASH=$(git rev-parse HEAD)
```

For continuous integration, use the environment variable provided by your system. For GitHub Actions pull request builds, use the pull request head SHA described earlier. Jenkins provides `GIT_COMMIT`, and GitLab CI provides `CI_COMMIT_SHA`.

Configure your bundler to inline the value:

- **Create React App:** Set `REACT_APP_GIT_HASH` and reference `process.env.REACT_APP_GIT_HASH`.
- **Next.js:** Set `NEXT_PUBLIC_GIT_HASH` and reference `process.env.NEXT_PUBLIC_GIT_HASH`.
- **Vite:** Set `VITE_GIT_HASH` and reference `import.meta.env.VITE_GIT_HASH`.
- **Webpack:** Use `DefinePlugin` to replace `process.env.GIT_HASH` with the build-time value.
- **Rollup:** Use `@rollup/plugin-replace` to replace `process.env.GIT_HASH` with the build-time value.
- `esbuild`: Use the `define` option to replace `process.env.GIT_HASH` with the build-time value.

For Webpack, add `DefinePlugin` to your build configuration:

JavaScript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```javascript
const webpack = require('webpack');

module.exports = {
  plugins: [
    new webpack.DefinePlugin({
      'process.env.GIT_HASH': JSON.stringify(process.env.GIT_HASH),
    }),
  ],
};
```

For Rollup, use `@rollup/plugin-replace`:

JavaScript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```javascript
import replace from '@rollup/plugin-replace';

export default {
  plugins: [
    replace({
      preventAssignment: true,
      'process.env.GIT_HASH': JSON.stringify(process.env.GIT_HASH),
    }),
  ],
};
```

For esbuild, use the `define` option:

JavaScript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```javascript
import * as esbuild from 'esbuild';

await esbuild.build({
  define: {
    'process.env.GIT_HASH': JSON.stringify(process.env.GIT_HASH),
  },
});
```

Reference the value in your Faro initialization:

JavaScript ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```javascript
import { initializeFaro } from '@grafana/faro-web-sdk';

initializeFaro({
  url: '$your-faro-collector-url',
  app: {
    name: '$your-app-name',
    version: '1.0.0',
    gitHash: process.env.GIT_HASH, // or import.meta.env.VITE_GIT_HASH for Vite
  },
});
```

## Verify the setup

For a new error, or an error that does not yet have a first-seen record:

1. Open **Frontend Observability** and select the app.
2. Open the **Errors** view.
3. Select an error to open its summary page.
4. Find the **Suspect commits** section.

When commit-hash correlation succeeds, the section shows **Commit that this error first appeared in** at the top. This commit is a direct signal from the app build and is not a likelihood score.

The section can also show ranked commits based on stack-trace-based matching, including when an introducing commit is present. Expand a result to see the matched paths. The introducing commit can also show a **Likely root cause** badge when its changed paths match the stack trace. Select a commit SHA or path to open the corresponding location in GitHub.

You can also verify commit-hash injection before investigating an error:

- **Build log:** Check for `[Faro] Git hash could not be resolved`. If it appears, the build did not inject a hash.
- **Bundle:** For the bundler-plugin path, open the browser developer tools console and run `window.__faroGitHash_<your-app-name>`. Expect a 40-character SHA.
- **Telemetry:** In the browser Network tab, inspect a Faro `/collect` request. `meta.app.gitHash` should be set on the payload.

## Interpret Suspect Commits results

Suspect Commits uses the error’s first-seen time rather than the time range selected elsewhere on the page. It searches up to 90 days before that time, widening the search progressively from the last week to the last month and then the last 90 days. The time label tells you how much history was searched.

The section can show two types of results:

- **Introducing commit:** A direct lookup of the SHA reported by the app build when the error was first observed.
- **Ranked candidates:** Commits that changed paths in the error stack trace. These are candidates for investigation, not proof of causation, and can appear below the introducing commit.

If an error was first recorded before commit-hash injection was enabled, later occurrences do not backfill the missing hash on that existing first-seen record. Verify the setup with an error whose first-seen record was created after hash injection was enabled.

## Troubleshoot missing results

Expand table

| What you see                                                      | What to check                                                                                                                                                                                                                                                                                                                 |
|-------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **GitHub datasource required**                                    | Install and configure the [GitHub data source](/docs/plugins/grafana-github-datasource/latest/configure/).                                                                                                                                                                                                                    |
| **GitHub datasource not selected**                                | An Editor or administrator must select a GitHub data source in **Settings &gt; GitHub** for this web app.                                                                                                                                                                                                                     |
| **GitHub repository not configured**                              | Enter the GitHub owner and repository name in **Settings &gt; GitHub**, then select **Save**.                                                                                                                                                                                                                                 |
| The **Suspect commits** section is missing                        | Check whether you previously hid the section. Restore it with the **Suspect commits** toggle on the error summary page.                                                                                                                                                                                                       |
| **No stacktrace available**                                       | Upload and verify [source maps](/docs/grafana-cloud/observe-and-act/monitor-applications/frontend-observability/configure/sourcemap-uploads/bundlers/) if you want stack-trace-based matching. The introducing commit can still work without a stack trace.                                                                   |
| **No application code found in stacktrace**                       | The error contains only dependency or browser-extension frames. Source maps cannot create app paths that the error did not report.                                                                                                                                                                                            |
| **First-seen record not available yet**                           | Absolute first-seen tracking has not captured this error yet. Wait for the error to occur again after tracking is available.                                                                                                                                                                                                  |
| **Could not load first-seen record**                              | Reload the page. If the problem persists, check the Frontend Observability backend status.                                                                                                                                                                                                                                    |
| **Could not load stacktrace**                                     | Reload the page. If the problem persists, check the status of the configured exception logs data source.                                                                                                                                                                                                                      |
| **No suspect commits found**                                      | Check the section tooltip. If it says **No related commit found in the queried repository**, no commit in the searched history changed the top stack-trace path, so the cause can be uncommitted code or code in another repository. Otherwise, check the displayed search window, repository mapping, and stack-trace paths. |
| The introducing commit is missing, but fallback results appear    | Verify that the build injects the intended 40-character SHA and that the SHA belongs to the configured repository. Force-pushed or rewritten commits can no longer be available.                                                                                                                                              |
| The app was instrumented before commit-hash injection was enabled | Use a newly recorded error to verify the hash. Existing first-seen records do not receive a later hash.                                                                                                                                                                                                                       |

## Next steps

- [Upload source maps with bundlers](/docs/grafana-cloud/observe-and-act/monitor-applications/frontend-observability/configure/sourcemap-uploads/bundlers/)
- [Configure the GitHub data source](/docs/plugins/grafana-github-datasource/latest/configure/)
- [Faro Web SDK](/docs/grafana-cloud/observe-and-act/monitor-applications/frontend-observability/instrument/)
