vitejs/vite · error · Error
Invalid glob: " " (resolved: " "). It must start with '/'…
Error message
Invalid glob: "${glob}" (resolved: "${resolved}"). It must start with '/' or './' What it means
resolveGlobPattern normalizes a single glob. It accepts globs starting with '/', './', '../', or '**', and tries to resolve anything else as a module id. If that resolution does not produce an absolute path, the glob is unusable and Vite throws, echoing both the raw glob and the resolved value.
Solutions
- Prefix the glob with './' for relative imports or '/' for absolute-from-root.
- If importing from a package, install/verify the package so resolveId returns an absolute path.
- For '#' subpath imports ensure the target exports map resolves; otherwise switch to an explicit relative/absolute glob.
- Check the printed 'resolved' value in the error — if it equals the raw glob, resolution failed entirely.
Example fix
// before
const mods = import.meta.glob('src/widgets/*.vue')
// after
const mods = import.meta.glob('./widgets/*.vue')
// or
const mods = import.meta.glob('/src/widgets/*.vue') Defensive patterns
Strategy: validation
Validate before calling
function validateGlob(glob) {
if (glob.startsWith('/') || glob.startsWith('./') || glob.startsWith('../') || glob.startsWith('**')) return
// bare spec: ensure it resolves
// (caller checks resolveId result is absolute before passing on)
throw new Error(`Glob must start with '/', './', '../', or '**': ${glob}`)
} Type guard
function isWellFormedGlob(glob): boolean {
return glob.startsWith('/') || glob.startsWith('./') || glob.startsWith('../') || glob.startsWith('**')
} Prevention
- Always prefix relative globs with './'.
- Use '/' for root-anchored globs.
- Run a quick lint pass over import.meta.glob arguments in CI.
When it happens
Trigger: Passing import.meta.glob a bare specifier (e.g. 'foo/*.js') or a path that neither matches the recognized prefixes nor resolves to an absolute module path. Also triggered by typos like 'src/x' (no leading './').
Common situations: Users assuming bare globs resolve like Node imports, copy-paste glob strings missing the './' prefix, or globs pointing at packages that are not installed (so resolveId returns the bare string unchanged, which is not absolute).
Related errors
- In virtual modules, all globs must start with '/'
- `input` cannot contain glob characters. They are reserved…
- config must export or return an object.
- currently full bundle mode is only available for client…
- Environment " " is not defined in the config.
AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11).
Data as JSON: /api/errors/50f32a04a4dd9d1f.
Report an issue: GitHub.
Appendix: 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 b4d66fee14)