{"id":"07ac75bf4b088621","repo":"vitest-dev/vitest","slug":"cannot-resolve-user-fixtures-see-errors-for-more","errorCode":null,"errorMessage":"Cannot resolve user fixtures. See errors for more information.","messagePattern":"Cannot resolve user fixtures\\. See errors for more information\\.","errorType":"exception","errorClass":"AggregateError","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/runtime/runner/fixture.ts","lineNumber":234,"sourceCode":"          continue\n        }\n        if (depName === fixture.name && !fixture.parent) {\n          errors.push(new FixtureDependencyError(`The \"${fixture.name}\" fixture depends on itself, but does not have a base implementation.`))\n          continue\n        }\n\n        if (TestFixtures._fixtureScopes.indexOf(fixture.scope) > TestFixtures._fixtureScopes.indexOf(dep.scope)) {\n          errors.push(new FixtureDependencyError(`The ${fixture.scope} \"${fixture.name}\" fixture cannot depend on a ${dep.scope} fixture \"${dep.name}\".`))\n          continue\n        }\n      }\n    }\n\n    if (errors.length === 1) {\n      throw errors[0]\n    }\n    else if (errors.length > 1) {\n      throw new AggregateError(errors, 'Cannot resolve user fixtures. See errors for more information.')\n    }\n    return registrations\n  }\n}\n\nconst cleanupFnArrayMap = new WeakMap<\n  object,\n  Array<() => void | Promise<void>>\n>()\n\nexport async function callFixtureCleanup(context: object): Promise<void> {\n  const cleanupFnArray = cleanupFnArrayMap.get(context) ?? []\n  for (const cleanup of cleanupFnArray.reverse()) {\n    await cleanup()\n  }\n  cleanupFnArrayMap.delete(context)\n}\n","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/runtime/runner/fixture.ts#L216-L252","documentation":"When `test.extend()`/`test.override()` registers fixtures via `parseUserFixtures` (fixture.ts:118), Vitest collects all validation errors (bad scope, unknown dependency, conflicting auto/scope, suite-level test-scoped fixture, etc.). If two or more distinct errors are found, they are bundled into an `AggregateError` with this message. A single error is thrown directly; this aggregate form is specifically for multiple simultaneous fixture problems.","triggerScenarios":"Registering several fixtures that each violate different rules at once — e.g. a fixture with an unknown scope, another depending on an undefined fixture, and a third with conflicting auto setting — all in one `test.extend({ ... })` call.","commonSituations":"Bulk fixture refactors introducing multiple regressions; typos in fixture option keys (`scope`, `auto`); renaming a fixture without updating dependents; copy-pasting fixtures into the wrong scope.","solutions":["Inspect `error.errors` (the AggregateError's sub-errors) to see each individual fixture problem.","Fix each sub-error one at a time, starting with the first listed.","Add fixtures incrementally to isolate which registration introduces errors.","Verify every fixture dependency name exists and every `scope` value is one of 'test'|'file'|'worker'."],"exampleFix":"// before: multiple bad fixtures\ntest.extend({\n  a: [() => {}, { scope: 'testt' }],          // unknown scope\n  b: ({ nonExistent }, use) => use(1),          // unknown dep\n  c: [() => {}, { auto: true }],\n  c2: [() => {}, { auto: false, scope: 'file' }],\n})\n// after: fix scope typo, remove unknown dep, align auto\ntest.extend({\n  a: [() => {}, { scope: 'test' }],\n  b: ({ a }, use) => use(a + 1),\n})","handlingStrategy":"validation","validationCode":"// Before test.extend, sanity-check fixture names and options.\nconst VALID_SCOPES = ['test', 'file', 'worker']\nfunction preValidateFixtures(defs: Record<string, any>, known: Set<string>) {\n  const errs: string[] = []\n  for (const [name, def] of Object.entries(defs)) {\n    const opts = Array.isArray(def) ? def[1] : {}\n    if (opts?.scope && !VALID_SCOPES.includes(opts.scope)) errs.push(`${name}: bad scope`)\n    // crude dep check omitted; rely on AggregateError for full graph\n  }\n  return errs\n}","typeGuard":null,"tryCatchPattern":"try {\n  test.extend(newFixtures)\n} catch (e) {\n  if (e instanceof AggregateError) {\n    for (const sub of e.errors) console.error(sub.message)\n  } else throw e\n}","preventionTips":["Add fixtures incrementally to isolate failures.","Inspect AggregateError.errors to enumerate every problem.","Keep a known-fixture-name list and validate dependencies against it in CI."],"tags":["fixtures","aggregate-error","validation","extend"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}