{"id":"5a48f2212e6ebcaf","repo":"vitest-dev/vitest","slug":"the-vcsprovider-module-vcsprovider-doesn-t-ha","errorCode":null,"errorMessage":"The vcsProvider module '${vcsProvider}' doesn't have a default export with `findChangedFiles` method.","messagePattern":"The vcsProvider module '(.+?)' doesn't have a default export with `findChangedFiles` method\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/vcs/vcs.ts","lineNumber":24,"sourceCode":"  root: string\n  changedSince?: string | boolean\n}\n\nexport interface VCSProvider {\n  // eslint-disable-next-line ts/method-signature-style\n  findChangedFiles(options: VCSProviderOptions): Promise<string[]>\n}\n\nexport async function loadVCSProvider(runner: ModuleRunner, vcsProvider: string | VCSProvider | undefined): Promise<VCSProvider> {\n  if (typeof vcsProvider === 'object' && vcsProvider != null) {\n    return wrapVCSProvider(vcsProvider)\n  }\n  if (!vcsProvider || vcsProvider === 'git') {\n    return new GitVCSProvider()\n  }\n  const module = await runner.import(vcsProvider) as { default: VCSProvider }\n  if (!module.default || typeof module.default !== 'object' || typeof module.default.findChangedFiles !== 'function') {\n    throw new Error(`The vcsProvider module '${vcsProvider}' doesn't have a default export with \\`findChangedFiles\\` method.`)\n  }\n  return wrapVCSProvider(module.default)\n}\n\nfunction wrapVCSProvider(provider: VCSProvider): VCSProvider {\n  return {\n    async findChangedFiles(options) {\n      const changedFiles = await provider.findChangedFiles(options)\n      return changedFiles.map(file => resolve(options.root, file))\n    },\n  }\n}\n","sourceCodeStart":6,"sourceCodeEnd":37,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/node/vcs/vcs.ts#L6-L37","documentation":"Thrown by `loadVcsProvider` (vcs.ts:24) when a custom `vcsProvider` module path is configured but the imported module's `default` export is missing, not an object, or lacks a `findChangedFiles` function. Vitest requires `{ default: { findChangedFiles(options) } }` so it can wrap and call the provider; any other shape is rejected.","triggerScenarios":"Setting `test.vcsProvider: './my-vcs.ts'` where the module has only named exports, exports a default that isn't an object, or exports an object without a `findChangedFiles` method; pointing at a module that is a utility file rather than a VCS provider.","commonSituations":"Authoring a custom VCS provider and forgetting the `default` export; renaming `findChangedFiles` to something else; pointing at the wrong file.","solutions":["Ensure the module has `export default { findChangedFiles(options) { /* ... */ } }`.","Verify the configured `vcsProvider` path resolves to the provider file.","Confirm `findChangedFiles` returns an array of absolute/relative changed file paths as expected by `wrapVCSProvider`."],"exampleFix":"// before\nexport const provider = { async changedFiles(opt) { /* ... */ } }\n// after\nexport default {\n  async findChangedFiles(options) { /* return string[] of changed files */ }\n}","handlingStrategy":"validation","validationCode":"const mod = await import(vcsProviderPath)\nconst def = mod.default\nif (!def || typeof def !== 'object' || typeof def.findChangedFiles !== 'function') {\n  throw new Error(`vcsProvider ${vcsProviderPath} must default-export { findChangedFiles }`)\n}","typeGuard":"const isVCSProvider = (m: unknown): m is { default: { findChangedFiles(o: any): Promise<string[]> } } =>\n  !!m && typeof m === 'object' && 'default' in m &&\n  typeof (m as any).default?.findChangedFiles === 'function'","tryCatchPattern":null,"preventionTips":["Author custom VCS providers with `export default { findChangedFiles }`.","Keep the method name exactly `findChangedFiles`.","Type-check the provider against the `VCSProvider` interface."],"tags":["vcs","custom-provider","default-export","config"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}