withastro/astro · warning

The glob() loader cannot be used for files in ${colors.bold(

Error message

The glob() loader cannot be used for files in ${colors.bold('src/content')} when legacy mode is enabled.

What it means

When legacy content collections are enabled (legacy.collectionsBackwardsCompat in astro.config.mjs) and a glob() loader matched files inside src/content, those files are skipped because the legacy pipeline owns src/content. If any files were skipped, the loader emits this warning explaining the glob() loader cannot be used there in legacy mode, followed by a count or list of the skipped files.

Source

Thrown at packages/astro/src/content/loaders/glob.ts:339

				files.map((entry) => {
					if (isConfigFile(entry)) {
						return;
					}
					return limit(async () => {
						const entryType = configForFile(entry);
						await syncData(entry, baseDir, entryType);
					});
				}),
			);

			const skipCount = skippedFiles.length;

			if (skipCount > 0) {
				const patternList = Array.isArray(globOptions.pattern)
					? globOptions.pattern.join(', ')
					: globOptions.pattern;

				logger.warn(
					`The glob() loader cannot be used for files in ${colors.bold('src/content')} when legacy mode is enabled.`,
				);
				if (skipCount > 10) {
					logger.warn(
						`Skipped ${colors.green(skippedFiles.length)} files that matched ${colors.green(patternList)}.`,
					);
				} else {
					logger.warn(`Skipped the following files that matched ${colors.green(patternList)}:`);
					skippedFiles.forEach((file) => logger.warn(`• ${colors.green(file)}`));
				}
			}

			// Remove entries that were not found this time
			untouchedEntries.forEach((id) => store.delete(id));

			if (!watcher) {
				return;
			}

View on GitHub (pinned to e294953aa8)

Solutions

  1. Migrate the collection off legacy mode (remove legacy.collectionsBackwardsCompat) so the glob loader can own src/content files
  2. Move the collection's source out of src/content (e.g. src/data/blog) and set an explicit base so the glob loader can read it while legacy mode stays on
  3. Delete the matched files from src/content if they are leftovers from an aborted migration

Example fix

// before: astro.config.mjs keeps legacy on, collection lives in src/content
export default defineConfig({ legacy: { collectionsBackwardsCompat: true } });

// after: move files to src/data/blog and point the loader there
const blog = defineCollection({ loader: glob({ pattern: '**/*.md', base: './src/data/blog' }) });
Defensive patterns

Strategy: validation

Validate before calling

// Guard config: refuse glob loaders targeting src/content under legacy mode
function assertNoLegacyOverlap(config: { legacy?: { collectionsBackwardsCompat?: boolean } }, base: string) {
  if (config.legacy?.collectionsBackwardsCompat && base.includes('/src/content')) {
    throw new Error('glob() loader cannot read src/content while legacy.collectionsBackwardsCompat is enabled');
  }
}

Prevention

When it happens

Trigger: Enabling legacy.collectionsBackwardsCompat while a content-layer collection's glob base (defaulted to the collection directory under src/content) matches files inside src/content.

Common situations: Projects mid-migration from Astro 4/5 legacy collections to the Content Layer that keep some collections under src/content; copy-pasting content-layer config into a legacy-mode project.

Related errors


AI-assisted analysis of withastro/astro@e294953aa8 (2026-08-18). Data as JSON: /api/errors/438da1c13d4a8eee. Report an issue: GitHub.