withastro/astro · error · Error

File path must be relative to the site root. Got: ${filePath

Error message

File path must be relative to the site root. Got: ${filePath}

What it means

Thrown as a plain Error (no AstroError code) from the scoped store's set() method when the supplied filePath begins with '/'. The store expects paths relative to the site root (no leading slash); absolute paths would break module resolution and the generated import map.

Source

Thrown at packages/astro/src/content/mutable-data-store.ts:371

				forEach(data, (_, val) => {
					if (typeof val === 'string' && val.startsWith(IMAGE_IMPORT_PREFIX)) {
						const src = val.replace(IMAGE_IMPORT_PREFIX, '');
						foundAssets.add(src);
					}
				});

				const entry: DataEntry = {
					id,
					data,
				};
				// We do it like this so we don't waste space stringifying
				// the fields if they are not set
				if (body) {
					entry.body = body;
				}
				if (filePath) {
					if (filePath.startsWith('/')) {
						throw new Error(`File path must be relative to the site root. Got: ${filePath}`);
					}
					entry.filePath = filePath;
				}

				if (foundAssets.size) {
					entry.assetImports = Array.from(foundAssets);
					this.addAssetImports(entry.assetImports, filePath);
				}

				if (digest) {
					entry.digest = digest;
				}
				if (rendered) {
					entry.rendered = rendered;
				}
				if (deferredRender) {
					entry.deferredRender = deferredRender;
					if (filePath) {

View on GitHub (pinned to d081033d5f)

Solutions

  1. Pass a relative path (no leading slash) — use posixRelative(root, absolutePath) to convert.
  2. If you have an absolute path, strip the project root prefix before passing it.
  3. Replicate the pattern used by the built-in file/glob loaders (they call posixRelative).

Example fix

// before
const filePath = '/src/content/posts/a.md';
context.store.set({ id, data, filePath });
// after
import { posixRelative } from 'astro/content/utils';
const filePath = posixRelative(config.root, absolutePath);
context.store.set({ id, data, filePath });
Defensive patterns

Strategy: validation

Validate before calling

import { posix } from 'node:path';
function toRelativeFilePath(p: string) {
  if (p.startsWith('/')) throw new Error(`filePath must be relative: ${p}`);
  return posix.normalize(p);
}

Type guard

const isRelativeFilePath = (p: string) => !p.startsWith('/');

Prevention

When it happens

Trigger: A loader calls context.store.set({ id, data, filePath: '/src/content/x.md' }) — passing an absolute or leading-slash path instead of a relative one.

Common situations: Using path.resolve() or fileURLToPath() without converting to a project-relative form; copying an OS-absolute path into filePath; loader code that prefixes '/' to normalize.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/94beaa003cdd7211. Report an issue: GitHub.