withastro/astro · error · AstroError
FileGlobNotSupported
FileGlobNotSupported
Error message
Glob patterns are not supported in the `file` loader. Use the `glob` loader instead.
What it means
Thrown synchronously by the file() loader constructor when the supplied fileName contains a '*' character. The file() loader reads a single concrete file; glob matching is the responsibility of the separate glob() loader, so the API refuses to silently misinterpret a glob pattern as a literal filename.
Source
Thrown at packages/astro/src/content/loaders/file.ts:27
type ParserOutput = Record<string, Record<string, unknown>> | Array<Record<string, unknown>>;
interface FileOptions {
/**
* the parsing function to use for this data
* @default JSON.parse or yaml.load, depending on the extension of the file
* */
parser?: (text: string) => Promise<ParserOutput> | ParserOutput;
}
/**
* Loads entries from a JSON file. The file must contain an array of objects that contain unique `id` fields, or an object with string keys.
* @param fileName The path to the JSON file to load, relative to the content directory.
* @param options Additional options for the file loader
*/
export function file(fileName: string, options?: FileOptions): Loader {
if (fileName.includes('*')) {
throw new AstroError(FileGlobNotSupported);
}
let parse: ((text: string) => any) | null = null;
const ext = fileName.split('.').at(-1);
if (ext === 'json') {
parse = JSON.parse;
} else if (ext === 'yml' || ext === 'yaml') {
parse = (text) =>
yaml.load(text, {
filename: fileName,
});
} else if (ext === 'toml') {
parse = toml.parse;
}
if (options?.parser) parse = options.parser;
if (parse === null) {View on GitHub (pinned to d081033d5f)
Solutions
- Switch to the glob() loader: import { glob } from 'astro/loaders' and use glob({ pattern: '...', base: ... }).
- If you meant a single file, remove the '*' from the path and pass a concrete filename to file().
Example fix
// before
import { file } from 'astro/loaders';
defineCollection({ loader: file('data/*.json') });
// after
import { glob } from 'astro/loaders';
defineCollection({ loader: glob({ pattern: 'data/*.json' }) }); Defensive patterns
Strategy: type-guard
Validate before calling
// Before calling file(), ensure the path is concrete
function assertConcreteFile(name: string) {
if (name.includes('*')) throw new Error(`Use glob() for patterns; file() got ${name}`);
} Type guard
const isGlobPattern = (p: string) => /[*?!]/.test(p) || p.includes('/**') || p.includes('{'); Prevention
- Reserve file() for a single concrete filename; reach for glob() for patterns.
- Lint content-config files for file() calls whose first arg contains '*'.
- Keep a cheat-sheet: file = one file, glob = many files.
When it happens
Trigger: Calling file('data/*.json') or file('**/config.yaml') — i.e. passing a glob pattern (containing *) as the fileName argument to the file() loader instead of using the glob() loader.
Common situations: Mistakenly importing { file } instead of { glob } from 'astro/loaders'; copying a glob pattern from elsewhere into a file() call; intending to load multiple files but picking the wrong loader.
Related errors
- FileParserNotFound
- Glob patterns cannot start with `/`. Set the `base` option t
- Live content collections must be defined in "src/live.config
- Collection loader for ${name} does not have a load method
- ContentLoaderReturnsInvalidId
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/2428c30903e86dfb.
Report an issue: GitHub.