{"record":{"id":"c16b487525174a5a","repo":"withastro/astro","slug":"fileparsernotfound","errorCode":"FileParserNotFound","errorMessage":"No parser was found for '${fileName}'. Pass a parser function (e.g. `parser: csv`) to the `file` loader.","messagePattern":"No parser was found for '(.+?)'\\. Pass a parser function \\(e\\.g\\. `parser: csv`\\) to the `file` loader\\.","errorType":"error_code","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/content/loaders/file.ts","lineNumber":50,"sourceCode":"\t}\n\n\tlet parse: ((text: string) => any) | null = null;\n\n\tconst ext = fileName.split('.').at(-1);\n\tif (ext === 'json') {\n\t\tparse = JSON.parse;\n\t} else if (ext === 'yml' || ext === 'yaml') {\n\t\tparse = (text) =>\n\t\t\tyaml.load(text, {\n\t\t\t\tfilename: fileName,\n\t\t\t});\n\t} else if (ext === 'toml') {\n\t\tparse = toml.parse;\n\t}\n\tif (options?.parser) parse = options.parser;\n\n\tif (parse === null) {\n\t\tthrow new AstroError({\n\t\t\t...FileParserNotFound,\n\t\t\tmessage: FileParserNotFound.message(fileName),\n\t\t});\n\t}\n\n\tasync function syncData(\n\t\tfilePath: string,\n\t\t{ logger, parseData, store, config, collection }: LoaderContext,\n\t) {\n\t\tlet data: Array<Record<string, unknown>> | Record<string, Record<string, unknown>>;\n\n\t\ttry {\n\t\t\tconst contents = await fs.readFile(filePath, 'utf-8');\n\t\t\tdata = await parse!(contents);\n\t\t} catch (error: any) {\n\t\t\tlogger.error(`Error reading data from ${fileName}`);\n\t\t\tlogger.debug(error.message);\n\t\t\treturn;","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/content/loaders/file.ts#L32-L68","documentation":"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.","triggerScenarios":"`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.","commonSituations":"Loading CSV, XML, or INI data files; files with uppercase extensions; teams assuming file() can read any text format out of the box.","solutions":["Pass a parser: `file('data/products.csv', { parser: (text) => Papa.parse(text, { header: true }).data })`.","Rename the file to use a supported lowercase extension (.json, .yml, .yaml, .toml) if the format already matches.","For odd extensions wrapping standard formats (e.g. `.jsonc`), supply the matching parser explicitly: `parser: JSON.parse`."],"exampleFix":"// before\nconst Products = defineCollection({ loader: file('data/products.csv') });\n\n// after\nimport Papa from 'papaparse';\nconst Products = defineCollection({\n  loader: file('data/products.csv', {\n    parser: (text) => Papa.parse(text, { header: true }).data,\n  }),\n});","handlingStrategy":"validation","validationCode":"import { extname } from 'node:path';\nconst BUILTIN = ['.json', '.yml', '.yaml', '.toml'];\n\nfunction needsParser(fileName: string): boolean {\n  return !BUILTIN.includes(extname(fileName).toLowerCase());\n}\n\nif (needsParser('data/products.csv')) {\n  // pass { parser: ... } or rename the file\n}","typeGuard":"const hasBuiltinParser = (fileName: string): boolean =>\n  ['.json', '.yml', '.yaml', '.toml'].includes(extname(fileName).toLowerCase());","tryCatchPattern":null,"preventionTips":["Use lowercase file extensions — the extension check is case-sensitive.","For CSV, wire a parser (e.g. papaparse) once in a shared helper instead of per collection."],"tags":["content-collections","file-loader","parser","file-format"],"backgroundTag":"unsupported-file-format","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}