ScreenshotNeo

BlogHow-to

How to Fix Cypress Support e2e.js File Format Errors

Fix Cypress e2e.js support-file errors by checking path, config scope, imports, browser compatibility, and module format.

By the ScreenshotNeo team1 October 20267 min read

Most Cypress e2e.js format errors come from one of five causes: the support-file path is wrong, the option is in the wrong configuration scope, more than one file matches, the file or an import cannot be compiled, or browser-bundled code imports a Node-only module.

Start by identifying which file actually failed. cypress/support/e2e.js is bundled and executed in the browser before each end-to-end spec. cypress.config.js and plugin code are loaded by Node and follow separate module-format rules.

1. Confirm the expected support-file location

The default end-to-end support entry point is:

cypress/support/e2e.js

JSX and TypeScript variants are also supported:

cypress/support/e2e.jsx
cypress/support/e2e.ts
cypress/support/e2e.tsx

Cypress loads this file before each spec, so a failure here can prevent every end-to-end test from starting. Check the spelling, case, extension, and working directory first.

2. Put supportFile under e2e

Since Cypress 10, the support-file setting belongs inside the testing-type object. A root-level supportFile is obsolete.

const { defineConfig } = require('cypress');

module.exports = defineConfig({
  e2e: {
    supportFile: 'cypress/support/e2e.js',
    baseUrl: 'http://localhost:3000'
  }
});

With ESM syntax:

import { defineConfig } from 'cypress';

export default defineConfig({
  e2e: {
    supportFile: 'cypress/support/e2e.js',
    baseUrl: 'http://localhost:3000'
  }
});

To disable the support file deliberately:

module.exports = {
  e2e: {
    supportFile: false
  }
};

Keep component-test configuration separate. For example, component.supportFile controls the component support entry point; e2e.supportFile controls end-to-end tests.

3. Check for duplicate matching files

One testing type must resolve to one unambiguous support entry point. Search for files that could match your configured path:

find cypress/support -maxdepth 1 -type f -print
find cypress -type f \( -name 'e2e.js' -o -name 'e2e.jsx' -o -name 'e2e.ts' -o -name 'e2e.tsx' \) -print

Remove or rename stale copies, then make the configuration point to the intended file. A duplicate can produce a support-file missing-or-invalid error even when one copy is valid.

4. Reduce the file to a known-good entry point

Replace the contents temporarily with a minimal browser-safe file:

// cypress/support/e2e.js
import './commands';

beforeEach(() => {
  // Shared browser-side setup goes here.
});

If this loads, restore imports and hooks one at a time. The first restored import that reproduces the error identifies the failing dependency.

Common JavaScript syntax problems include an unmatched brace, an unterminated string, a typo in an import path, and using a syntax feature that your configured bundler cannot parse. Run a parser or formatter against the file and inspect the line reported by Cypress.

5. Check every import and dependency

The support file can import other files. Cypress bundles that dependency graph, so an error in a helper can appear as an e2e.js preparation error.

// Good: browser-compatible helper
import { formatUserName } from '../../src/shared/formatUserName';

// Also good: Cypress commands registered in a browser-compatible module
import './commands';

Verify that each imported package is installed in the project that runs Cypress:

npm ls package-name
npm install package-name

For a local file, verify the exact relative path and filename case. This matters on case-sensitive CI systems even if a case-insensitive local filesystem allowed the import.

6. Keep Node-only work out of e2e.js

The support file and its imports run in the browser context. Do not import Node-only modules such as fs, database drivers, or server-side SDKs into that bundle.

Put Node-side work in setupNodeEvents, then call it from a test with cy.task():

const { defineConfig } = require('cypress');
const fs = require('node:fs');

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', {
        readFixture(filePath) {
          return fs.readFileSync(filePath, 'utf8');
        }
      });

      return config;
    }
  }
});
// In a spec file or browser-side support helper
cy.task('readFixture', 'fixtures/example.json').then((contents) => {
  expect(contents).to.contain('example');
});

This separation also keeps the pre-spec browser bundle smaller and makes failures easier to locate.

7. Distinguish support-file errors from config-format errors

If the error names cypress.config.js or a plugin, inspect module format separately from the support file.

File Loader selection Typical syntax
.mjs ES modules import and export default
.cjs CommonJS require and module.exports
.js Nearest package.json type module selects ESM; omitted or commonjs selects CommonJS

Cypress 15.17.0 introduced this Node-style selection for configuration and plugin files and does not retry with the other loader after a load failure. Align the extension, the nearest package type, and the syntax in the file.

This rule concerns config and plugin loading. The support file still travels through Cypress’s browser bundling pipeline, so a config-module fix will not repair a browser-incompatible support import.

8. A complete working example

Project layout:

cypress/
  e2e/
    smoke.cy.js
  support/
    e2e.js
    commands.js
cypress.config.js
package.json

cypress.config.js:

const { defineConfig } = require('cypress');

module.exports = defineConfig({
  e2e: {
    baseUrl: 'http://localhost:3000',
    supportFile: 'cypress/support/e2e.js',
    setupNodeEvents(on, config) {
      return config;
    }
  }
});

cypress/support/e2e.js:

import './commands';

beforeEach(() => {
  cy.clearCookies();
});

cypress/support/commands.js:

Cypress.Commands.add('loginByApi', (email, password) => {
  cy.request('POST', '/api/login', { email, password });
});

cypress/e2e/smoke.cy.js:

describe('home page', () => {
  it('loads', () => {
    cy.visit('/');
    cy.contains('Welcome').should('be.visible');
  });
});

9. Diagnostic checklist

  1. Read the first file path and line number in the Cypress error.
  2. Decide whether it is cypress/support/e2e.js, cypress.config.js, or a plugin.
  3. Confirm e2e.supportFile is nested under e2e.
  4. Confirm the configured path exists and its case matches exactly.
  5. Search for duplicate support files.
  6. Temporarily reduce e2e.js to one known-good import.
  7. Restore imports one at a time and install missing packages.
  8. Move fs, database clients, and other Node-only code to setupNodeEvents and invoke it with cy.task().
  9. For config errors, align .mjs, .cjs, or package.json type with the syntax.
  10. Restart the Cypress process after changing configuration or dependencies.

10. Common errors and fixes

Message or symptom Likely cause Fix
Support file missing or invalid Wrong scope, path, extension, missing file, or duplicate match Check e2e.supportFile, verify the file, and remove duplicates.
We found an error preparing your test file Syntax error, unresolved import, missing dependency, or browser-incompatible module Read the reported line, reduce the file, then restore imports incrementally.
Error Loading Config mentioning supportFile Legacy root-level option Move it under e2e or component.
Cannot use import statement outside a module Usually a config/plugin loader mismatch Check the extension and nearest package type; use matching ESM or CommonJS syntax.
Module not found Wrong relative path, package not installed, or case mismatch Check the path, run npm ls, install the package, and verify case.
Built-in Node module cannot be resolved Node-only import entered the browser bundle Move the code to setupNodeEvents and expose a task.

11. Performance and reliability considerations

Because Cypress loads the support bundle before every spec, avoid importing large libraries or doing network and database work at module top level. Register commands and hooks in the support file, but defer expensive work to the test that needs it or to a Node task.

Keep shared hooks deterministic. A failing global beforeEach can make unrelated specs appear broken. Prefer explicit timeouts for known slow operations and keep browser setup independent of external services when possible.

On CI, reproduce the same working directory, Node version, package lockfile, and case-sensitive paths used by local development. A clean install can reveal undeclared dependencies that happened to exist in a developer’s environment.

12. Or skip the browser setup

If the goal is to capture a Cypress page or test artifact rather than debug Cypress itself, ScreenshotNeo returns a screenshot with one GET request. Its cookie and consent handling accepts the banner like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture.

See the ScreenshotNeo API documentation for the available options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and whether the shot was billed. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots.

Create a free ScreenshotNeo account to get started.

13. FAQ

Should I name the file e2e.js?

Use that name and location for the default setup. A custom filename works when e2e.supportFile points to it.

Can I disable the support file?

Yes. Set e2e.supportFile to false, but remove any tests that depend on commands or hooks registered there.

Why does a Node import fail only in Cypress?

The support file is bundled for browser execution. Move Node APIs into setupNodeEvents and call them with cy.task().

Does changing package.json type fix every import error?

No. It affects Node-loaded config and plugin files. Browser-bundled support imports must still be valid for Cypress’s support pipeline.