---
title: Troubleshooting TurboSnap
description: Speed up tests by detecting file changes with Git
sidebar: { order: 4, label: "Troubleshooting" }
slug: "turbosnap/troubleshooting"
---

import { YouTubeCallout } from "../../components/YouTubeCallout";

# Troubleshooting your TurboSnap setup

<YouTubeCallout
  client:load
  id="y_xji7aPi1s"
  summary="How to prepare your local Storybook for debugging"
/>

## Why are no changes being detected?

If the build output shows no story files being detected by changes, there might be an issue matching the git changes with the files in your Storybook build. Use the `--debug` flag for more information about what Chromatic is doing.

Another reason that changes may be missed is if the changed files aren't directly included in the webpack build; use the [`externals` flag](/docs/turbosnap/setup#specify-external-files-to-trigger-a-full-re-test-when-they-change) to tell Chromatic about this.

## Why are changes not being detected correctly?

Teams frequently use an index file ([barrel file](https://basarat.gitbook.io/typescript/main-1/barrel)) to simplify imports. This practice allows for easier importing, such as accessing a component from `@component-library` instead of specifying the full path like `@component-library/elements/table`. However, the usage of barrels impacts TurboSnap's ability to detect changes.

When encountering a barrel file, TurboSnap relies on Webpack's tree-shaking abilities to accurately identify changes. Otherwise, a modification in `@component-library/elements/table` would prompt changes in all files importing from the barrel file, meaning all files that import from `@component-library`.

Therefore, if you use barrel files, you'll want to ensure that Webpack tree-shaking (dead-code-elimination) is working properly. Here are some tips:

1. Use ES2015 module syntax (i.e., import and export)
2. Build using `production` mode (`NODE_ENV`) to enable [various optimizations](https://webpack.js.org/configuration/mode/#usage) including minification and tree-shaking.
3. Make sure that compilers do not automatically convert your ES2015 module syntax into CommonJS modules. This is the default behavior of the popular Babel preset `@babel/preset-env`. See the [documentation](https://babeljs.io/docs/babel-preset-env#modules) for more details.

## Why is TurboSnap testing more stories than the ones I changed?

TurboSnap identifies **updated files** to test their stories. For instance, if you modify a single story in the `Button.stories.js` file, TurboSnap will test all stories in that file because it cannot pinpoint changes to an individual story.
You can review how many stories were tested in the TurboSnap tooltip.

## Why are full rebuilds required?

Full rebuilds can be required for various reasons (see the list in [how it works](/docs/turbosnap#how-it-works)). Another scenario where a full rebuild will also be required is due to a change to a `package.json` or lock file for a subproject that doesn't affect the Storybook (we need to be very conservative as we cannot tell if a change to a lock file could affect `node_modules` imported by Storybook).

## Why is my build failing with an <code>Out of memory error</code>?

An `Out of Memory` error typically happens when the Node.js process runs out of allocated memory, especially if your project has a large dependency tree or TurboSnap is enabled. Here are a few steps that can help resolve this issue:

- **Increase Node.js memory allocation:** Try rerunning Chromatic’s CLI with a higher memory limit by setting `NODE_OPTIONS=--max_old_space_size=4096` (4GB) or higher. This provides more memory to Node.js, which can help with larger builds.

- **Adjust CI runner memory settings:** Make sure your CI runner has sufficient memory. Chromatic recommends a minimum of 4GB, and if needed, up to 8GB. Some CI providers may require specific configurations to allocate more memory to certain steps or to the entire runner environment.

- **Force full rebuilds on lock file changes:** Set the `MAX_LOCK_FILE_SIZE` environment variable to 1 to ensure a full rebuild occurs whenever the lock file changes. This can help prevent OOM errors.

Builds are split between your environment and Chromatic’s. Processes that require access to your code (like dependency tracing) run in your environment, while tasks like the Capture process run on Chromatic’s end.

## Why do merge commits test more changes than I expect?

Ordinarily, TurboSnap uses git to find all files that have changed since the [ancestor build](/docs/branching-and-baselines#find-the-ancestor-builds) to determine which components/stories to snapshot. The changed file behavior is more complex with merge commits because there are two "ancestor builds".

When you have a merge commit, Chromatic considers **any file that has changed since either ancestor's commit** to decide if a story needs to be re-snapshotted. In other words, the union of the git changes.

The reason for this behavior relates to what Chromatic does when it chooses not to re-snapshot a story. In such case, it "copies" the snapshot for the story from the ancestor build, knowing (due to the git check) that the story cannot have changed in the meantime.

In the case of merge commits, Chromatic does not know ahead of time which side of the merge the snapshot might be copied from because that involves running the [complete baseline selection](/docs/branching-and-baselines#calculate-a-snapshot-baseline-from-the-ancestor-builds) process, so it needs to be conservative and allow for changes on either branch.

## Does TurboSnap work with squash/rebase merge?

TurboSnap is compatible with squash and merge rebasing as of version 6.6+. Please update your package to get support.

## What do the TurboSnap bail reasons in my usage report mean?

Your [usage data (CSV report)](/docs/billing#export-usage-data-as-a-csv) can help you faster identify opportunities to improve your TurboSnap configuration. The "TurboSnaps Bail Reason" column tells you what caused TurboSnap triggered a full rebuild. Here's what each reason means:

### `changedExternalFiles`

TurboSnap bailed due to matching `externals`.

You may need to check your glob pattern or revisit the paths you're including with `externals` if these changes are unexpected.

### `changedPackageFiles`

TurboSnap bailed due to one or more package file changes (`package.json`, `package-lock.json`, `yarn.lock`).

This bail should be expected from time to time as dependencies are updated, but can become more of an issue if you run out of a monorepo or have dependencies in subdirectories. If you find this happening frequently, consider using `untraced` to [avoid re-testing on changes to your package control files](/docs/turbosnap/setup#avoid-re-testing-on-changes-to-package-control-files).

### `changedStaticFiles`

TurboSnap bailed due to matching static file (`--static-dir`).

This message should only present to customers using TurboSnap with older Storybook versions, since `--static-dir` was deprecated in Storybook 8. Customers on Storybook 8+ need to add their static dirs using `externals`. This error may indicate that you need to check the value you've configured for `--static-dir`.

### `changedStorybookFiles`

TurboSnap bailed due to a change in Storybook config (`.storybook` dir files, such as `main.js|ts` and `preview.js|ts`).

You may have made changes to one of the files within your Storybook configuration, or to a dependency that is being imported by your configuration. It's important to keep in mind that second part, since it's common practice to import decorators into the `preview.js` config.

Additionally, if you're utilizing barrel/index files (whether directly importing in your `preview.js` or in a file that `preview.js` is dependent on), it's likely to cause more bails since [a change to any of these modules would cause any file that imports the index file to be considered "dirty"](/docs/turbosnap/setup#avoid-re-testing-dependent-stories-when-certain-files-changed), even if it's not using the changed module.

### `invalidChangedFiles`

TurboSnap bailed due to missing git history.

TurboSnap is having issues retrieving your git history. This commonly happens when a repo is shallow cloning, which can be fixed by setting your fetch depth to `0` in your `.yml` workflow file. Another common cause of this issue is when customers use GitHub Actions with the `pull_request` event. If this is the case, you'll want to make sure you [set the correct `ref` in your checkout step](/docs/github-actions#recommended-configuration-for-build-events).

### `missingStatsFile`

TurboSnap bailed due to missing stats file.

Since the stats file is needed for TurboSnap to analyze your dependencies, make sure your Storybook script includes `--stats-json`.

### `noAncestorBuild`

TurboSnap bailed due to not finding an ancestor build for the commit.

This bail reason is reserved for when no ancestor build is found at all for a commit. This can be due to rebasing, squash-merging, force-pushing, or running against ephemeral merge commits. If it's happening on builds that don't fit those categories, it may indicate an issue with fetching your git history.

### `rebuild`

TurboSnap bailed because the commit is a rerun of a previous build, based on the baseline build having the same commit and branch name.

Most reruns are intentional, but if you weren't expecting the ones you're seeing, this may indicate you need to check your CI workflow to see what could be kicking off an additional build for the same commit.