withastro/astro · error · AstroUserError
Live content collections must be defined in "src/live.config
Error message
Live content collections must be defined in "src/live.config.ts" file. Check the loaders used in "${importerFilename}" to ensure you are not using a live loader to define a build-time content collection. What it means
When `defineCollection` is given an object `loader` that lacks a `load` function but exposes `loadEntry`/`loadCollection`, Astro treats it as a live loader placed in a build-time config file — a category error. Live loaders belong in `src/live.config.ts`; build-time loaders (with `load`) belong in `src/content/config.ts`.
Source
Thrown at packages/astro/src/content/config.ts:203
message: AstroErrorData.LiveContentConfigError.message(
'Collections in a live config file must use `defineLiveCollection`.',
importerFilename,
),
});
}
if ('loader' in config) {
if (config.type && config.type !== CONTENT_LAYER_TYPE) {
throw new AstroUserError(
`A content collection is defined with legacy features (e.g. missing a \`loader\` or has a \`type\`). Check your collection definitions in ${importerFilename ?? 'your content config file'} to ensure that all collections are defined using the current properties.`,
);
}
if (
typeof config.loader === 'object' &&
typeof config.loader.load !== 'function' &&
('loadEntry' in config.loader || 'loadCollection' in config.loader)
) {
throw new AstroUserError(
`Live content collections must be defined in "src/live.config.ts" file. Check the loaders used in "${importerFilename ?? 'your content config file'}" to ensure you are not using a live loader to define a build-time content collection.`,
);
}
config.type = CONTENT_LAYER_TYPE;
}
if (!config.type) config.type = 'content';
return config;
}
View on GitHub (pinned to d081033d5f)
Solutions
- Move the collection to `src/live.config.ts` and define it via `defineLiveCollection`.
- Or swap the loader for a build-time loader (`load`-based) such as `glob()` or `file()`.
- Confirm whether the loader you imported is a live or build-time loader from its package docs.
Example fix
// before — src/content/config.ts
import { myLiveLoader } from 'some-integration/live';
export const collections = { cms: defineCollection({ loader: myLiveLoader() }) };
// after — src/live.config.ts
import { defineLiveCollection } from 'astro:content';
import { myLiveLoader } from 'some-integration/live';
export const collections = { cms: defineLiveCollection({ loader: myLiveLoader() }) }; Defensive patterns
Strategy: validation
Validate before calling
if (typeof config.loader === 'object' && typeof config.loader.load !== 'function' && ('loadEntry' in config.loader || 'loadCollection' in config.loader)) {
throw new Error('This is a live loader — move it to src/live.config.ts');
} Type guard
function isBuildLoader(l) { return !!l && typeof l.load === 'function'; } Prevention
- Check whether a loader exposes `load` (build-time) vs `loadCollection`/`loadEntry` (live) before placing it.
- Keep live loaders out of `src/content/config.ts`.
When it happens
Trigger: Passing a live loader (object with `loadEntry`/`loadCollection` but no `load`) to `defineCollection` inside `src/content/config.ts`.
Common situations: Using a live loader integration (e.g. a CMS live loader) inside the build-time config; mixing up which config file is which after renaming.
Related errors
- LiveContentConfigError
- Collection loader for ${name} does not have a load method
- ContentLoaderReturnsInvalidId
- ContentLoaderInvalidDataError
- ExpectedImageOptions
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/7eadecf7844832cb.
Report an issue: GitHub.