{"record":{"id":"9e7dc82f8fa20fe1","repo":"vitejs/vite","slug":"in-virtual-modules-all-globs-must-start-with","errorCode":null,"errorMessage":"In virtual modules, all globs must start with '/'","messagePattern":"In virtual modules, all globs must start with '/'","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/plugins/importMetaGlob.ts","lineNumber":457,"sourceCode":"  if (!matches.length) return null\n\n  const s = new MagicString(code)\n\n  const staticImports = (\n    await Promise.all(\n      matches.map(\n        async ({\n          globsResolved,\n          isRelative,\n          options,\n          index,\n          start,\n          end,\n          onlyKeys,\n          onlyValues,\n        }) => {\n          if (!dir && !options.base && isRelative) {\n            throw new Error(\"In virtual modules, all globs must start with '/'\")\n          }\n\n          const cwd = getCommonBase(globsResolved) ?? root\n          const files = (\n            await glob(globsResolved, {\n              absolute: true,\n              cwd,\n              dot: !!options.exhaustive,\n              expandDirectories: false,\n              caseSensitiveMatch: options.caseSensitive ?? true,\n              ignore: options.exhaustive ? [] : ['**/node_modules/**'],\n              extglob: false,\n            })\n          )\n            .filter((file) => file !== id)\n            .sort()\n\n          const objectProps: string[] = []","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/vitejs/vite/blob/b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab/packages/vite/src/node/plugins/importMetaGlob.ts#L439-L475","documentation":"import.meta.glob globs are resolved relative to the importing module's directory. Virtual modules have no real file directory (dir is falsy), so a relative glob (./foo, ../foo) cannot be resolved. Vite requires absolute globs (starting with '/') when there is no dir, optionally combined with options.base.","triggerScenarios":"Calling import.meta.glob with a relative pattern from inside a virtual module (a module id that is not a real file, e.g. a plugin-generated module with no file path), where isRelative is true and no options.base is supplied.","commonSituations":"A plugin generates a virtual entry and that virtual code calls import.meta.glob('./routes/*.js'). Framework integrations that inject virtual modules containing glob calls hit this.","solutions":["Use absolute globs from project root in the virtual module: import.meta.glob('/src/routes/*.js').","Pass options.base so Vite can resolve relative globs against it: import.meta.glob('./routes/*.js', { base: '/src' }).","Move the glob call out of the virtual module into a real file and have the virtual module import that file.","If you control the plugin, compute absolute paths at generation time instead of relying on relative resolution."],"exampleFix":"// before (inside a virtual module)\nconst routes = import.meta.glob('./routes/*.js')\n// after\nconst routes = import.meta.glob('/src/routes/*.js')\n// or\nconst routes = import.meta.glob('./routes/*.js', { base: '/src' })","handlingStrategy":"validation","validationCode":"// In virtual modules, force absolute globs\nfunction safeGlob(glob, isVirtual, base) {\n  if (isVirtual && (glob.startsWith('./') || glob.startsWith('../')) && !base) {\n    throw new Error(`Virtual glob must be absolute: ${glob}`)\n  }\n  return glob\n}","typeGuard":"function isAbsoluteGlob(glob): boolean {\n  return glob.startsWith('/') || glob.startsWith('**')\n}","tryCatchPattern":null,"preventionTips":["In virtual modules, always use globs starting with '/' or pass options.base.","Centralize glob calls in real files when possible.","Document for plugin users that virtual contexts require absolute globs."],"tags":["glob","virtual-modules","import-meta-glob"],"backgroundTag":null,"analyzedSha":"b4d66fee14d970f45b8a6f3d7d6aee73ca9b88ab","analyzedAt":"2026-08-11T11:49:19.515Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}