withastro/astro · error · AstroError

FileParserNotFound

FileParserNotFound

Error message

No parser was found for '${fileName}'. Pass a parser function (e.g. `parser: csv`) to the `file` loader.

What it means

The file() loader has built-in parsers for .json, .yml/.yaml, and .toml only (detected case-sensitively from the extension). For any other extension you must pass a `parser` function in options; otherwise it throws FileParserNotFound at config-load time.

Solutions

  1. Pass a parser: `file('data/products.csv', { parser: (text) => Papa.parse(text, { header: true }).data })`.
  2. Rename the file to use a supported lowercase extension (.json, .yml, .yaml, .toml) if the format already matches.
  3. For odd extensions wrapping standard formats (e.g. `.jsonc`), supply the matching parser explicitly: `parser: JSON.parse`.

Example fix

// before
const Products = defineCollection({ loader: file('data/products.csv') });

// after
import Papa from 'papaparse';
const Products = defineCollection({
  loader: file('data/products.csv', {
    parser: (text) => Papa.parse(text, { header: true }).data,
  }),
});
Defensive patterns

Strategy: validation

Validate before calling

import { extname } from 'node:path';
const BUILTIN = ['.json', '.yml', '.yaml', '.toml'];

function needsParser(fileName: string): boolean {
  return !BUILTIN.includes(extname(fileName).toLowerCase());
}

if (needsParser('data/products.csv')) {
  // pass { parser: ... } or rename the file
}

Type guard

const hasBuiltinParser = (fileName: string): boolean =>
  ['.json', '.yml', '.yaml', '.toml'].includes(extname(fileName).toLowerCase());

Prevention

When it happens

Trigger: `file('data/products.csv')` with no options; also `file('DATA.JSON')` — the extension check is case-sensitive, so an uppercase `.JSON` finds no built-in parser either.

Common situations: Loading CSV, XML, or INI data files; files with uppercase extensions; teams assuming file() can read any text format out of the box.

Related errors


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

Appendix: source

Thrown at packages/astro/src/content/loaders/file.ts:50

	}

	let parse: ((text: string) => any) | null = null;

	const ext = fileName.split('.').at(-1);
	if (ext === 'json') {
		parse = JSON.parse;
	} else if (ext === 'yml' || ext === 'yaml') {
		parse = (text) =>
			yaml.load(text, {
				filename: fileName,
			});
	} else if (ext === 'toml') {
		parse = toml.parse;
	}
	if (options?.parser) parse = options.parser;

	if (parse === null) {
		throw new AstroError({
			...FileParserNotFound,
			message: FileParserNotFound.message(fileName),
		});
	}

	async function syncData(
		filePath: string,
		{ logger, parseData, store, config, collection }: LoaderContext,
	) {
		let data: Array<Record<string, unknown>> | Record<string, Record<string, unknown>>;

		try {
			const contents = await fs.readFile(filePath, 'utf-8');
			data = await parse!(contents);
		} catch (error: any) {
			logger.error(`Error reading data from ${fileName}`);
			logger.debug(error.message);
			return;

View on GitHub (pinned to 52e6c34790)