{"record":{"id":"64d02195df0ad51c","repo":"angular/angular-cli","slug":"project-options-project-does-not-have-a-test","errorCode":null,"errorMessage":"Project \"${options.project}\" does not have a \"test\" target with a supported builder.","messagePattern":"Project \"(.+?)\" does not have a \"test\" target with a supported builder\\.","errorType":"exception","errorClass":"SchematicsException","httpStatus":null,"severity":"error","filePath":"packages/schematics/angular/vitest-browser/index.ts","lineNumber":40,"sourceCode":"} from '../utility/dependency';\nimport { JSONFile } from '../utility/json-file';\nimport { latestVersions } from '../utility/latest-versions';\nimport { getWorkspace } from '../utility/workspace';\nimport { Builders } from '../utility/workspace-models';\nimport { Schema as VitestBrowserOptions } from './schema';\n\nexport default function (options: VitestBrowserOptions): Rule {\n  return async (host: Tree, _context: SchematicContext) => {\n    const workspace = await getWorkspace(host);\n    const project = workspace.projects.get(options.project);\n\n    if (!project) {\n      throw new SchematicsException(`Project \"${options.project}\" does not exist.`);\n    }\n\n    const testTarget = project.targets.get('test');\n    if (testTarget?.builder !== Builders.BuildUnitTest) {\n      throw new SchematicsException(\n        `Project \"${options.project}\" does not have a \"test\" target with a supported builder.`,\n      );\n    }\n\n    if (testTarget.options?.['runner'] === 'karma') {\n      throw new SchematicsException(\n        `Project \"${options.project}\" is configured to use Karma. ` +\n          'Please migrate to Vitest before adding browser testing support.',\n      );\n    }\n\n    const packageName = options.package;\n    if (!packageName) {\n      return;\n    }\n\n    const dependencies = [packageName];\n    if (packageName === '@vitest/browser-playwright') {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/schematics/angular/vitest-browser/index.ts#L22-L58","documentation":"The vitest-browser schematic requires the target project's \"test\" target to already use the unit-test (Vitest) builder (Builders.BuildUnitTest). If the target is missing or built with a different builder, this SchematicsException is thrown because browser mode can only be layered onto a Vitest-based test setup.","triggerScenarios":"Running the vitest-browser schematic on a project whose angular.json either has no \"test\" target at all, or whose test target's builder is not the @angular/build unit-test builder (e.g. karma builder or a custom builder string).","commonSituations":"Projects still on Karma, projects created before the Vitest migration where the test target was never converted, hand-edited angular.json with a custom test builder, or applying the schematic to a library without a test target.","solutions":["First run the unit-test/Vitest migration schematic (`ng generate init-vitest` or the project's migration command) so the test target uses @angular/build:unit-test, then rerun vitest-browser.","Manually set the test target's builder to @angular/build:unit-test in angular.json.","Add a \"test\" target if the project has none, configured with the Vitest builder.","Verify with `ng config projects.<name>.architect.test.builder` that the builder is the supported one before running the schematic."],"exampleFix":"// before (angular.json)\n\"test\": { \"builder\": \"@angular-devkit/build-angular:karma\", ... }\n// after\n\"test\": { \"builder\": \"@angular/build:unit-test\", ... }","handlingStrategy":"validation","validationCode":"const ws = JSON.parse(fs.readFileSync('angular.json', 'utf8'));\nconst test = ws.projects?.[name]?.architect?.test ?? ws.projects?.[name]?.targets?.test;\nif (test?.builder !== '@angular/build:unit-test') {\n  throw new Error(`Project \"${name}\" must first migrate its test target to the Vitest unit-test builder.`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await ngGenerate(['vitest-browser', '--project', name]);\n} catch (e) {\n  if (String((e as Error).message).includes('supported builder')) {\n    await ngGenerate(['init-vitest', '--project', name]); // migrate first, then retry\n  } else throw e;\n}","preventionTips":["Complete the Karma-to-Vitest migration before layering browser testing on a project.","Check the test target builder string in angular.json equals @angular/build:unit-test.","Ensure every project that will use vitest-browser has an explicit \"test\" target."],"tags":["schematics","vitest","builder"],"backgroundTag":"unsupported-test-builder","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}