withastro/astro · warning

Content config not loaded

Error message

Content config not loaded

What it means

On dev start/restart, Astro loads src/content.config.ts into a status of loaded, does-not-exist, or error. When the file exists but did not load cleanly, the content layer is not started; the actual error is printed just above via logger.error('content', ...), and this warning summarizes that no content config is active for this session.

Source

Thrown at packages/astro/src/core/dev/dev.ts:130

		attachDataStoreInvalidation(store, restart.container.viteServer, restart.container.settings);
	}
	await attachContentServerListeners(restart.container);

	const config = globalContentConfigObserver.get();
	if (config.status === 'error') {
		logger.error('content', config.error.message);
	}
	if (config.status === 'loaded' && store) {
		const contentLayer = globalContentLayer.init({
			settings: restart.container.settings,
			logger,
			watcher: restart.container.viteServer.watcher,
			store,
		});
		contentLayer.watchContentConfig();
		await contentLayer.sync();
	} else if (config.status !== 'does-not-exist') {
		logger.warn('content', 'Content config not loaded');
	}

	// Start listening to the port
	const devServerAddressInfo = await startContainer(restart.container);

	restart.bindCLIShortcuts();
	logger.info(
		'SKIP_FORMAT',
		msg.serverStart({
			startupTime: performance.now() - devStart,
			resolvedUrls: restart.container.viteServer.resolvedUrls || { local: [], network: [] },
			host: restart.container.settings.config.server.host,
			base: restart.container.settings.config.base,
			astroVersionProvider: new BuildTimeAstroVersionProvider(),
			textStyler: piccoloreTextStyler,
		}),
	);

View on GitHub (pinned to e294953aa8)

Solutions

  1. Scroll up to the logger.error('content', ...) line — it contains the real cause (syntax error, missing module, etc.)
  2. Fix src/content.config.ts and make sure every imported package is installed
  3. Save the file to trigger a dev-server restart; the content layer re-syncs automatically

Example fix

// before — src/content.config.ts (broken import)
import { glob } from 'astro/loader'; // typo: package is 'astro/loaders'
export const collections = { blog: { loader: glob({ pattern: '**/*.md' }) } };

// after
import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';

const blog = defineCollection({
  loader: glob({ pattern: '**/*.md', base: './src/content/blog' }),
});
export const collections = { blog };
Defensive patterns

Strategy: validation

Validate before calling

// surface content.config.ts load errors before starting the app
try {
  await import('./src/content.config.ts');
} catch (e) {
  console.error('content.config.ts failed to load:', e.message);
  process.exitCode = 1;
}

Prevention

When it happens

Trigger: A syntax error, invalid export shape, or failed import (e.g. a loader or zod package not installed) in src/content.config.ts leaves status !== 'loaded' and !== 'does-not-exist' — commonly a transient broken state while the dev server auto-restarts mid-edit.

Common situations: Saving a half-finished edit to content.config.ts; adding an import for a package that is not installed; TypeScript-only failures like importing types without type annotations.

Related errors


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