cypress-io/cypress · error · Error

Could not resolve "${dep}". Do you have "@angular-devkit/bui

Error message

Could not resolve "${dep}". Do you have "@angular-devkit/build-angular" and "@angular-devkit/core" installed?

What it means

Thrown inside the Angular CLI module loader loop when require.resolve or tsImport fails for one of the @angular-devkit modules (build-angular/src/webpack/utils, build-angular/src/index, core/src/index). The loader uses tsx's tsImport to dynamically import these ESM-only Angular packages; any failure is caught and rethrown as a single, dependency-installation-focused message. It is essentially a peer-dependency / resolution guard, not a logic error.

Source

Thrown at npm/webpack-dev-server/src/helpers/angularHandler.ts:203

    { getCommonConfig },
    { getStylesConfig },
    { logging },
  ] = await Promise.all(angularCLiModules.map(async (dep) => {
    try {
      let depPath = require.resolve(dep, { paths: [projectRoot] })
      // NOTE: @cypress/webpack-dev-server is a CJS package, but we need to import some ESM files and absolute imports.
      // since import statements in TypeScript will get transpiled down to CommonJS require statements, we want to use tsx to leverage
      // an ESM style import here, which supports CommonJS and ESM.
      const { tsImport } = require('tsx/esm/api')

      // NOTE: on Windows, fully qualified paths (ex: C:\Users\username\project\blah) need to be prefixed with `file://` to be properly resolved.
      depPath = platform() === 'win32' ? `file://${toPosix(depPath)}` : depPath

      const module = await tsImport(depPath, __filename)

      return module
    } catch (e) {
      throw new Error(`Could not resolve "${dep}". Do you have "@angular-devkit/build-angular" and "@angular-devkit/core" installed?`)
    }
  }))

  return {
    generateBrowserWebpackConfigFromContext,
    getCommonConfig,
    getStylesConfig,
    logging,
  }
}

export async function getAngularJson (projectRoot: string): Promise<AngularJson> {
  // NOTE: @cypress/webpack-dev-server is a CJS package, but find-up +6.0.0 is an ESM only package.
  // In order to dynamically import the find-up package, we need to use tsx to do so until @cypress/webpack-dev-server is an ESM-only package,
  // which would be a breaking change to @cypress/webpack-dev-server and cypress.
  const { tsImport } = require('tsx/esm/api')

  const { findUp } = await tsImport('find-up', __filename) as typeof import('find-up')

View on GitHub (pinned to 0d85fdc912)

Solutions

  1. Run `npm install --save-dev @angular-devkit/build-angular @angular-devkit/core` (or yarn/pnpm equivalent) at the project root Cypress is testing.
  2. Verify the installed versions match the project's Angular major version (`ng version`).
  3. If using a monorepo, ensure the package is resolvable from projectRoot — add it to the workspace's package.json or use nohoist / pnpm overrides as appropriate.
  4. On Windows, confirm the resolved path is absolute and on the same drive; the file:// prefix logic at line 197 only fires for win32.
  5. Reinstall tsx if the failure is inside tsImport itself (`npm ls tsx`).

Example fix

// before
# Angular project package.json (devDependencies)
{}
// after
# Angular project package.json (devDependencies)
{
  "@angular-devkit/build-angular": "^19.0.0",
  "@angular-devkit/core": "^19.0.0"
}
Defensive patterns

Strategy: validation

Validate before calling

const required = [
  '@angular-devkit/build-angular',
  '@angular-devkit/core',
]
for (const dep of required) {
  try { require.resolve(dep, { paths: [projectRoot] }) }
  catch { console.error(`Missing ${dep} — install it before running Cypress CT`) }
}

Type guard

function canResolveAngularDevkit (projectRoot: string): boolean {
  const deps = [
    '@angular-devkit/build-angular/src/webpack/utils',
    '@angular-devkit/build-angular/src/index.js',
    '@angular-devkit/core/src/index.js',
  ]
  return deps.every((d) => {
    try { require.resolve(d, { paths: [projectRoot] }); return true } catch { return false }
  })
}

Prevention

When it happens

Trigger: Running Cypress component tests with the Angular webpack-dev-server when @angular-devkit/build-angular or @angular-devkit/core is not installed in node_modules reachable from projectRoot, when versions are mismatched (e.g. Angular 19 devkit on an Angular 18 project), or when the package was hoisted in a way that breaks require.resolve paths.

Common situations: Fresh clone where Angular dev dependencies were marked optional and skipped, monorepo hoisting (yarn workspaces) that places @angular-devkit outside the resolution scope, Windows path issues that the file:// prefix logic at line 197 does not cover, or a broken tsx install.

Related errors


AI-assisted analysis of cypress-io/cypress@0d85fdc912 (2026-08-12). Data as JSON: /api/errors/8953c1b1c8ad4ced. Report an issue: GitHub.