withastro/astro · error · AstroError

LiveContentConfigError

LiveContentConfigError

Error message

Live collections must be defined in a `src/live.config.ts` file. Check your collection definitions in ${path.relative(fileURLToPath(settings.config.root), configPathname)}.

What it means

Astro validates your content config with zod on load. When validation fails and at least one collection in the invalid config has type: 'live', Astro throws this variant of LiveContentConfigError naming the config file — type: 'live' is not part of the content config schema, so its presence is the likely reason validation failed.

Solutions

  1. Move all type: 'live' collections out of the file named in the error into src/live.config.ts, switching them to defineLiveCollection.
  2. Review the zod issues printed just above the throw — they list every invalid property in the config.
  3. Re-run astro sync or restart the dev server to re-validate.

Example fix

// before: src/content.config.ts exports a live collection
export const collections = {
  news: { type: 'live', loader },
};

// after: src/live.config.ts
import { defineLiveCollection } from 'astro:content';
export const collections = {
  news: defineLiveCollection({ loader }),
};
Defensive patterns

Strategy: validation

Validate before calling

// CI guard: content.config.ts must not export collections with type: 'live'
// simplest form: forbid the literal in the file
import { readFileSync } from 'node:fs';
if (/type:\s*['"]live['"]/.test(readFileSync('src/content.config.ts', 'utf8'))) {
  throw new Error('live collections must move to src/live.config.ts');
}

Prevention

When it happens

Trigger: Exporting a collections object from src/content.config.ts where any collection has type: 'live'; re-exporting live collection definitions into the content config from a shared module.

Common situations: Following live-collections docs and defining them in the wrong file; splitting config across multiple files and merging them back into one export.

Related errors


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

Appendix: source

Thrown at packages/astro/src/content/utils.ts:532

	const configPathname = fileURLToPath(contentPaths.config.url);
	const unparsedConfig = await environment.runner.import(configPathname);

	const config = contentConfigParser(logger).safeParse(unparsedConfig);
	if (config.success) {
		// Generate a digest of the config file so we can invalidate the cache if it changes
		const hasher = await xxhash();
		const digest = hasher.h64ToString(await fs.promises.readFile(configPathname, 'utf-8'));
		return { ...config.data, digest };
	} else {
		const message = config.error.issues
			.map((issue) => `  → ${colors.green(issue.path.join('.'))}: ${colors.red(issue.message)}`)
			.join('\n');
		logger.error('content', `There was a problem with your content config:\n\n${message}\n`);
		const liveCollections = Object.entries(unparsedConfig.collections ?? {}).filter(
			([, collection]: [string, any]) => collection?.type === LIVE_CONTENT_TYPE,
		);
		if (liveCollections.length > 0) {
			throw new AstroError({
				...AstroErrorData.LiveContentConfigError,
				message: AstroErrorData.LiveContentConfigError.message(
					'Live collections must be defined in a `src/live.config.ts` file.',
					path.relative(fileURLToPath(settings.config.root), configPathname),
				),
			});
		}
		return undefined;
	}
}

async function autogenerateCollections({
	config,
	settings,
	fs,
	logger,
}: {
	config?: ContentConfig;

View on GitHub (pinned to e294953aa8)