withastro/astro · error · Error

Collection loader for

Error message

Collection loader for ${name} does not have a load method

What it means

During content-layer sync (build or dev), each collection's loader must be either a function (treated as a simple loader) or an object with a `load()` method. This Error is thrown from ContentLayer.sync when a collection's `loader` object has no `load` function — typically a live or malformed loader that reached the sync stage without going through defineCollection's config-time validation.

Solutions

  1. Implement `load(context)` on the loader object — the build-time loader contract
  2. If the loader is actually a live loader (loadEntry/loadCollection), move that collection to `src/live.config.ts` with `defineLiveCollection`
  3. If the loader is a plain function, pass it directly as `loader` — functions are wrapped into simple loaders automatically

Example fix

// before
const loader = { loadEntry, loadCollection }; // no load()
collections.posts = { loader };

// after
const loader = {
  async load(context) {
    // read entries and store them via context.store
  },
};
collections.posts = defineCollection({ loader });
Defensive patterns

Strategy: type-guard

Type guard

function isBuildTimeLoader(loader) {
  return typeof loader === 'function' || typeof loader?.load === 'function';
}

if (!isBuildTimeLoader(collection.loader)) {
  // object without load() — either implement load() or move the collection to live.config.ts
  throw new TypeError('collection loader must be a function or an object with load()');
}

Prevention

When it happens

Trigger: A collections config built programmatically (objects assembled without `defineCollection`, or cast to bypass its checks) whose loader implements `loadEntry`/`loadCollection` but not `load`; a hand-written loader missing the `load` method; a `loader: {}` typo.

Common situations: Configs constructed dynamically or imported from JS modules that skip defineCollection validation; switching a loader type while a stale build cache references the old shape; custom loaders authored without the `load` method.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/0885c1b5fc6495de. Report an issue: GitHub.

Appendix: source

Thrown at packages/astro/src/content/content-layer.ts:343

								_internal: {
									rawData: undefined,
									filePath,
								},
							},
							{ ...collection, schema },
							false,
						),
					loaderName,
					refreshContextData: options?.context,
				});

				if ('loader' in collection) {
					if (typeof collection.loader === 'function') {
						return simpleLoader(collection.loader as CollectionLoader<{ id: string }>, context);
					}

					if (!collection.loader?.load) {
						throw new Error(`Collection loader for ${name} does not have a load method`);
					}

					return collection.loader.load(context);
				}
			}),
		);
		this.#validateReferences(contentConfig.config.collections, logger);
		await fs.mkdir(this.#settings.config.cacheDir, { recursive: true });
		await fs.mkdir(this.#settings.dotAstroDir, { recursive: true });
		const assetImportsFile = new URL(ASSET_IMPORTS_FILE, this.#settings.dotAstroDir);
		await this.#store.writeAssetImports(assetImportsFile);
		const modulesImportsFile = new URL(MODULES_IMPORTS_FILE, this.#settings.dotAstroDir);
		await this.#store.writeModuleImports(modulesImportsFile);
		await this.#store.waitUntilSaveComplete();
		logger.info('Synced content');
		if (this.#settings.config.experimental.contentIntellisense) {
			await this.regenerateCollectionFileManifest();
		}

View on GitHub (pinned to 52e6c34790)