vitejs/vite · error · Error
Invalid glob: "${glob}" (resolved: "${resolved}"). It must s
Error message
Invalid glob: "${glob}" (resolved: "${resolved}"). It must start with '/' or './' What it means
Thrown when resolving a single `import.meta.glob` pattern whose specifier is neither absolute nor made relative (`./`/`../`). After attempting to resolve the pattern via the resolve pipeline, if the result does not start with `/`, Vite rejects it because glob patterns must be path-rooted to be expanded safely.
Source
Thrown at packages/vite/src/node/plugins/importMetaGlob.ts:687
}
if (glob[0] === '/') return pre + posix.join(root, glob.slice(1))
if (glob.startsWith('./')) return pre + posix.join(dir, glob.slice(2))
if (glob.startsWith('../')) return pre + posix.join(dir, glob)
if (glob.startsWith('**')) return pre + glob
const isSubImportsPattern = glob[0] === '#' && glob.includes('*')
const resolved = normalizePath(
(await resolveId(glob, importer, {
custom: { 'vite:import-glob': { isSubImportsPattern } },
})) || glob,
)
if (isAbsolute(resolved)) {
return pre + globSafeResolvedPath(resolved, glob)
}
throw new Error(
`Invalid glob: "${glob}" (resolved: "${resolved}"). It must start with '/' or './'`,
)
}
export function getCommonBase(globsResolved: string[]): null | string {
const bases = globsResolved
.filter((g) => g[0] !== '!')
.map((glob) => {
let { base } = picomatch.scan(glob)
// `scan('a/foo.js')` returns `base: 'a/foo.js'`
if (posix.basename(base).includes('.')) base = posix.dirname(base)
return base
})
if (!bases.length) return null
let commonAncestor = ''View on GitHub (pinned to 89620f09af)
Solutions
- Prefix the glob with `/` (absolute from project root) or `./` (relative to the importing file).
- If globbing inside a package, ensure the package is installed and its exports resolve; use a subpath pattern with leading `./`.
- Avoid bare-specifier globs; resolve to a concrete path first.
Example fix
// before
const modules = import.meta.glob('components/*.vue');
// after
const modules = import.meta.glob('./components/*.vue'); Defensive patterns
Strategy: validation
Validate before calling
function validateGlobPattern(glob) {
if (glob.startsWith('/') || glob.startsWith('./') || glob.startsWith('../') || glob.startsWith('!')) return;
throw new Error(`Glob must start with '/' or './': ${glob}`);
}
// globs.forEach(validateGlobPattern); Type guard
function isValidGlobPrefix(glob) {
return /^(\/|\.\/|\.\.\/|!)/.test(glob);
} Prevention
- Always prefix glob patterns with `/` (absolute) or `./` (relative).
- Avoid bare package-specifier globs; resolve them to concrete paths first.
- Add an ESLint/custom check banning `import.meta.glob('...')` without a `./` or `/` prefix.
When it happens
Trigger: In `await resolveId(glob, importer, ...)`, the resolved value is not absolute (`isAbsolute(resolved)` is false) — e.g. a bare package specifier that did not resolve to a file path, or a glob that resolves to a relative/bare string.
Common situations: Globbing a bare package import (`import.meta.glob('lodash/*.js')`) where the package cannot be resolved to an absolute path; subpath patterns that don't resolve; a glob missing a leading `./` or `/`.
Related errors
- failed to resolve rolldownOptions.input value: ${JSON.string
- In virtual modules, all globs must start with '/'
- { runtime: "${result.runtime}" } is not supported for assets
- `renderLegacyChunks` and `renderModernChunks` cannot be both
- @vitejs/plugin-legacy does not support library mode.
AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03).
Data as JSON: /data/errors/50f32a04a4dd9d1f.json.
Report an issue: GitHub.